Compare commits

...

287 Commits

Author SHA1 Message Date
matlabbe
32c051320c UCv2Qt: fixed min/max of depth to grayscale conversion for CV_32FC1 type 2017-01-06 16:57:47 -05:00
matlabbe
74ae1429a1 Camera tool: fixed compilation warning 2017-01-06 13:57:07 -05:00
matlabbe
00c93abd1b Memory: ignore reextract features when registration is not visual 2017-01-06 08:20:32 -05:00
matlabbe
7fa559247d DbViewer: disable "Add" button if one of the current images selected is not in the graph 2017-01-05 21:10:26 -05:00
matlabbe
8895173a2b Memory::computeTransform(): Fixed empty "from" image when reextract features is true and ICP-only registration is used 2017-01-05 19:31:18 -05:00
matlabbe
f20cb6ff52 Preferences: fixed map opacity limited to 0.75 min. Making sure that normalized variances are set to epsilon if result is 0. 2017-01-05 18:08:20 -05:00
matlabbe
4b12fb3a9a Normalize variance in refined/added loop closure (DbViewer) 2017-01-05 17:23:55 -05:00
matlabbe
716337b71a normalize variance in loop closure 2017-01-05 17:22:49 -05:00
matlabbe
dfb965cfa9 Fixed bundler exportation not using local transform 2017-01-04 17:49:59 -05:00
matlabbe
91f78b54d8 bump android version 2017-01-03 22:34:16 -05:00
matlabbe
ac1c5f81ae fixed some compilation warnings 2017-01-03 22:14:21 -05:00
matlabbe
6abed48af6 0.11.13. OdometryF2M: fixed/improved bundle adjustment option. OptimizerG2O: now doing stereo BA instead of mono BA (interface of Optimizer::optimzeBA() has slightly changed to include depth in word references). Registration and Odometry set angular and linear variances separately. RegistrationVis set x100 smaller variance for rotation. Added keypoints3D member to SensorData. Added Transform::getAngle() for convenience. Odometry normalizes variances. RtabmapThread does variance summation when frames are discarded. Updated how variance is computed by util3d::estimateMotion3Dto2D(), ignoring very large variance from the computation (stereo issue with very far matched features). MainWindow: added option to align with ground truth or not (default true as before), added for odometry statistics (including bundle stuff), update ground truth statistics every time a graph is loaded/optimized. CameraRGB can now load odometry files (to fake an input odometry). PreferencesDialog: Added option to Odometry so it can use a different registration approach than the default one (the one used for loop closure). Parameters: added new g2o/Solver option 3 (Eigen), added g2o/RobustKernelDelta, g2o/Baseline and Odom/VisKeyFrameThr. Database: from 0.11.13, ignoring patch version when comparing is database version is newer than app version used. 2017-01-03 21:05:00 -05:00
matlabbe
6550a52cee fixed #152 2016-12-05 15:53:19 -05:00
matlabbe
cd62e67011 Localization: Revert mapCorrection transform to one before being lost (when odom can be computed again) 2016-12-05 15:16:04 -05:00
matlabbe
e5524ddc1d Tango: fixed black clouds. Rtabmap: only add latest optimized pose to graph if localized. 2016-12-05 13:27:29 -05:00
matlabbe
3c17049084 Tango: Added Rendering Options... -> Mesh Rendering -> Mesh Decimation 2016-12-03 21:49:40 -05:00
matlabbe
d2287ab9f4 Backward compatibility (DBViewer, DBReader) with old database format not saving CameraModel's image size, cx and cy 2016-12-02 13:43:44 -05:00
matlabbe
a5f4468c54 Fixed build warnings about variables not used in CameraRGBD and CameraStereo classes (depending on which sensor is available) 2016-12-02 12:29:38 -05:00
matlabbe
f2dbfa9b33 StereoCameraModel: baseline computed with Tx of left camera too. Fixed QMultiComboBox not showing on windows. Avoid updating grid view if there are no local grids in signatrues. Clear cached data of StatsItem when detecting smaller timestamp than last ones. 2016-12-01 21:46:09 -05:00
matlabbe
d0dddaf7cc DbViewer: fixed bug where null links were added when added links doen't have enough inliers. g2o/Optimizer: changed back to Levenberg as GaussNewton seems worst on Kinect multi-session mapping 2016-12-01 11:59:49 -05:00
matlabbe
40d0be5828 Preferences: fixed groupbox modified signal not sent when reading a config file 2016-11-30 21:24:17 -05:00
matlabbe
d879491a58 Fixed #149 2016-11-30 14:25:01 -05:00
matlabbe
4d585cbb11 Fixed bug where Grid/MaxObstacleHeight didn't work when the ground is not observable 2016-11-28 14:02:06 -05:00
matlabbe
2f6d7f81cc Fixed accumulated words bug in highest hypothesis view 2016-11-27 20:55:53 -05:00
matlabbe
3363772ce5 CloudViewer: added backface culling option on right-click menu. MainWindow: removed error msg on wrong decimation (util3d already handle this case) 2016-11-27 20:10:05 -05:00
matlabbe
1910cef3d1 g2o/Optimizer changed default to 1 (Gauss Newton) 2016-11-27 18:32:48 -05:00
matlabbe
121446d648 Removed parameter "OdomF2M/FixedMapPath". GUI: added odometry disabled option. Rtabmap can now localize even if odometry input is null (only in localization mode). 2016-11-27 14:30:11 -05:00
matlabbe
693f623e5e Fixed GUI crash when using rectified RGB only (with odometry). Fixed empty local map when loading a fixed local map for OdometryF2M. 2016-11-25 19:52:34 -05:00
matlabbe
da1cac1e55 Tango: fixed map not optimized when opening a database 2016-11-25 16:05:14 -05:00
matlabbe
22089a9e45 Tango: Fixed supporting devices for appropriate listing in play store (only for Tango-enabled phones/tablets) 2016-11-25 15:35:18 -05:00
matlabbe
e65db3cba5 Tango: fixed localization mode not working 2016-11-25 15:20:42 -05:00
matlabbe
5b183d9105 DbViewer: do the max optimization error test when adding a new loop closure (rejecting it if it fails) 2016-11-24 15:09:16 -05:00
matlabbe
2a43a95ddd flann serialize unordered_map compilation error (#126): modified define name to avoid conflicts with the one defined in OpenCV 2016-11-23 17:36:38 -05:00
matlabbe
23bb5d5147 DBDriver: when an empty database url is provided, an empty database "in memory" is used by default. Tango: fixed second database not recorded in Data Recorder mode (now creating a new one on save). Mapping parameters are saved in database instead of the one used to record data (Data Recorder mode). 2016-11-23 15:13:09 -05:00
matlabbe
639896b309 CloudViewer: fixed dark textures 2016-11-21 19:10:30 -05:00
matlabbe
3d5699ef4a Tango: fixed second database not saved when hitting Save two times consecutively 2016-11-21 18:13:56 -05:00
matlabbe
1c41882bf0 bump tango version 2016-11-21 17:13:32 -05:00
matlabbe
14908e3a11 rtabmap: refining neighbor links uses computeIcpTransform() instead of computeTransform() (to ignore Visual registration, which adds more errors most of the time). When database is in RAM, we can close under a different name than the one used when the database was loaded.
Tango: Added Append Mode option (only start a new map after being localized, default true) and the old map is still shown for convenience until localization. Increased minInliers to 25. Increased ICP correspondenceRatio to 0.5. Decreased time to open a database. Saving doesn't close the database anymore and overwrite only if we save with the same name. Removed ICP refining from standard optimization.
2016-11-21 17:09:04 -05:00
matlabbe
4c559a3191 Preview: reduced minimum size of the window 2016-11-21 12:02:29 -05:00
matlabbe
0802f9158c MainWindow: backward compatibility: load default parameters for those not saved in a db 2016-11-18 16:59:14 -05:00
matlabbe
ceb5c38ca3 util3d: find maximum decimation if the one set is not compatible (instead of returning an empty cloud) 2016-11-18 16:19:41 -05:00
matlabbe
f0d36e71a1 Memory: fixed missing parameters in database on close 2016-11-18 15:53:35 -05:00
matlabbe
e809b30cb9 Tango: removed post-processing done after resuming the app 2016-11-18 14:18:04 -05:00
matlabbe
e5db40e4ae Tango: Fixed a bug where gain compensation was done while mapping (causing big lags) 2016-11-18 13:07:53 -05:00
matlabbe
43ff7e4b3e rtabmap-console: added "skip" option for convenience 2016-11-17 16:18:19 -05:00
matlabbe
a3afc249ef Fixed old parameters ignored when reading config file from GUI 2016-11-17 16:08:55 -05:00
matlabbe
ed83d90603 RTAB-Map.exe can be started with parameters as arguments (in similar way than rtabmap-console) 2016-11-16 17:39:17 -05:00
matlabbe
daf0a9c6e8 cleanup 2016-11-16 14:20:14 -05:00
matlabbe
4271fb37e9 Tango: Forcing landscape mode only (#143) 2016-11-16 12:56:30 -05:00
matlabbe
8560baca87 Fixed fx=0 error when running multi-session databases 2016-11-16 12:28:33 -05:00
matlabbe
d73394abd8 DBViewer: show local transform in calibration parameters, increased precision of small numbers < 0.001 for parameters toolbox 2016-11-16 11:39:44 -05:00
matlabbe
f6cca3313a Tango: Using tango_support library to get depth to color transform (#143), poses are in device frames and camera local transform is from device to camera (including optical rotation), "720" Mode is now called "HD Mode" 2016-11-16 10:13:16 -05:00
matlabbe
76edd53e40 Update showlogs.m 2016-11-15 17:54:43 -05:00
matlabbe
cb31a717cf rtabmap-console: added fake initialization at startup to make sure all external libraries are loaded before processing the first frame 2016-11-15 16:49:58 -05:00
matlabbe
b9b3dcb5e3 QMultiComboBox: removed "DONT USE IT" msg 2016-11-15 10:21:19 -05:00
matlabbe
acf55e0c9b DatabaseViewer: fixed just 50 last values shown on statistics view 2016-11-15 09:52:24 -05:00
matlabbe
c40456a2ec ULogger::unregsiterCurrentThread: unregister ALL values related to same thread 2016-11-15 08:53:26 -05:00
matlabbe
6d9f1828c6 fixed iterator error on some systems (#145) 2016-11-15 08:47:41 -05:00
matlabbe
9276607920 Added Bundle Adjustment options to OdometryF2M (OdomF2M/BundleAdjustment) and RegistrationVis (Vis/BundleAdjustment). Added logger thread filter. RegistrationVis: Copy back corresponding input word IDs to output words when available. Memory::computeTransform() added option to use already computed corespondences if possible (proximity detection by time uses this). Updated Optimizer::optimizeBA() interface. 2016-11-14 19:54:31 -05:00
matlabbe
9fbd02b06d fixed bug of wrong likelihood when KDTree is used with Kp/IncrementalFlann=false (maybe related to #144) 2016-11-10 14:07:00 -05:00
matlabbe
4885a9e65a fixed a warning 2016-11-10 10:22:47 -05:00
matlabbe
98851ed686 ExportCloudsDialog: decreased minimum triangle size from 2 to 1 2016-11-10 09:48:51 -05:00
matlabbe
edcd92fbb7 DBViewer: merged Refine (visual) and Refine (ICP) in the same Refine action (registration used is defined by Reg/Strategy value). Updated how detect more loop closures work in MainWindow and DBViewer (using current registration parameters, visual and/or icp) 2016-11-09 16:44:08 -05:00
matlabbe
fdcfb3eb7c Merge pull request #142 from TomasBedrnik/upstream
Fix missing space in ostream operator <<  for Transform
2016-11-08 13:17:31 -05:00
Tomas
55ff45064f Fix missing space in ostream << operator for Transform 2016-11-08 19:40:34 +02:00
matlabbe
f88eadd312 Merge pull request #141 from TomasBedrnik/upstream
Fix bug with ostream operator<< for Transform
2016-11-07 13:31:01 -05:00
Tomas
874e9dafc2 Fix bug with ostream operator>> for Transform 2016-11-07 14:42:01 +02:00
matlabbe
d6b334ab02 nump tango version 2016-11-04 17:32:29 -04:00
matlabbe
efbee6796f Tango: sorting files on Open 2016-11-04 17:03:06 -04:00
matlabbe
cdeba51ccd fixed typo 2016-11-04 16:46:30 -04:00
matlabbe
7fd3d9f331 Tango: added mesh smoothing, show file size on Open, default timestamp filename on save/export 2016-11-04 16:39:52 -04:00
matlabbe
c8d5a446ea fixed Ubuntu build (Eigen error in util2d::fastBilateralFiltering) 2016-11-03 17:43:32 -04:00
matlabbe
fe19d277ac Fixed OdomF2M ICP local scan transform bug (was not in 0.11.8) 2016-11-03 17:27:01 -04:00
matlabbe
a7971373a6 Added bilateral filtering option. CloudViewer: lighting and edge visibility options. 2016-11-03 17:04:31 -04:00
matlabbe
70dbac10c7 Updated .travis.yml with email notifications 2016-11-03 11:22:11 -04:00
matlabbe
82b352d519 Updated .travis.yml with ros paths 2016-11-03 11:12:16 -04:00
matlabbe
421926f7ac Updated .travis.yml 2016-11-03 11:03:47 -04:00
matlabbe
53d555dceb Updated .travis.yml with g2o, openni2 and octomap dependencies 2016-11-03 11:00:31 -04:00
matlabbe
043e288d70 Fixed assert "((int)path.size() < = maxGraphDepth*2+1)" when Mem/ReduceGraph=On 2016-11-02 13:06:38 -04:00
matlabbe
8718bb4ff1 Fixed #137 2016-11-01 12:04:10 -04:00
matlabbe
0a06648c02 Updated Tango namespace (see Qianru release notes) for Phab 2 Pro 2016-10-31 23:16:24 -04:00
matlabbe
276992d654 Fixed laser scans not saved when Mem/BinDataKept is false (they are still required for scan matching) 2016-10-31 14:29:32 -04:00
matlabbe
f07bb17442 Find/Link explicitly OpenCL libraries if Freenect2 is detected (moved in main CMakeLists.txt to be added to exported in RTABMapConfig.cmake) 2016-10-31 14:28:17 -04:00
matlabbe
2529952982 ExportClouds: set minimum K (for normal estimation) to 3. Also added a check if the created cloud is empty. 2016-10-31 11:29:07 -04:00
matlabbe
e3c290269b cloudFromDepthRGB: Don't assert if decimation is wrong, just throw error and return empty cloud 2016-10-31 11:10:16 -04:00
matlabbe
4bcb31e532 Refactored GainCompsensator for backward compatibility with PCL <1.7.2 2016-10-30 17:46:11 -04:00
matlabbe
768c864766 Image Decimation can now be negative, meaning that decimation is done from RGB size instead of depth. If Depth size is smaller than RGB, it may be upsampled depending on the decimation value. Export Dialog: Fixed MLS not done even when checked. 2016-10-30 16:03:23 -04:00
matlabbe
20a5d80647 bump tango version 2016-10-29 18:42:39 -04:00
matlabbe
a09aebeca4 Tango: Added Data Recorder mode (See Mapping menu) 2016-10-29 18:14:25 -04:00
matlabbe
9e0b45e27a Fixed "UNIQUE constraint failed: Statistics.id" error when loading a previous map with last id saved in Statistics not in Node table (this happened when ignored locations are not saved to database). 2016-10-29 18:12:27 -04:00
matlabbe
9123889876 Tango: Added full gain compensation option 2016-10-27 15:35:19 -04:00
matlabbe
d06abbbd91 Tango: updated to use TangoPointCloud callback (fixed deprecated TangoXYZij) 2016-10-27 14:44:11 -04:00
matlabbe
8f90d25468 Tango: added camera movement when moving 2 fingers 2016-10-27 14:22:21 -04:00
matlabbe
69219eb340 Fixed MLS still done when not visible if checked before 2016-10-26 20:41:33 -04:00
matlabbe
185f03985e Refactored GainCompensator. Export Dialog: Added option to do full gain compensation with all locations. 2016-10-26 19:03:44 -04:00
matlabbe
d102c43f9a ZED: Added self calibration option (default false) 2016-10-25 16:06:55 -04:00
matlabbe
063e019653 Export Images: fixed images still saved when cancelling the dialog 2016-10-25 14:54:02 -04:00
matlabbe
49cb35175f fixed build error backward compatibility pcl 1.7 < pcl 1.8 2016-10-24 16:31:57 -04:00
matlabbe
5d1ea43b9e Fixed build error on Windows 2016-10-24 14:44:49 -04:00
matlabbe
a1c3a60f87 DB Viewer: added message box at the end of extracting images 2016-10-23 18:32:07 -04:00
matlabbe
60c406d6ec EipolarGeometry: added missing dictionary.update() 2016-10-23 14:01:44 -04:00
matlabbe
7b2bf9ac13 GUI: Fixed crash when adding Texture Dense Mesh to CloudViewer 2016-10-21 19:34:29 -04:00
matlabbe
856b83ac53 GUI: Fixing some minor Export dialog bugs (texture option disabled on export or failing to save mesh without extension set) 2016-10-21 16:56:29 -04:00
matlabbe
4017db1d15 fixed #132 2016-10-21 16:54:32 -04:00
matlabbe
5a24bcfe51 GUI: added option to show octomap as a point cloud (less GPU power required) 2016-10-18 13:29:40 -04:00
matlabbe
73268c2af2 GUI: Fixed current image and loop closure image features not shown when Mem/BinDataKept is false 2016-10-18 12:27:14 -04:00
matlabbe
bcc6354c04 fixed strange ellipse shape in GraphView with Qt5 2016-10-17 19:30:44 -04:00
matlabbe
1853cfde9b ImageView: Fixed feature's depth value when depth image is not the same size as the RGB image 2016-10-17 13:30:35 -04:00
matlabbe
07ff1a7717 Fixed save/loading of binary distortion model on Windows #128 2016-10-14 16:03:08 -04:00
matlabbe
0ce6ef8d8d CLAMS: cleanup eigen_extensions.h, models can be saved/loaded in binary (*.bin) or ascii (*.txt) formats 2016-10-14 15:24:24 -04:00
matlabbe
e13454fe3f Memory: Disabled occupancy grid update if no depth image 2016-10-14 13:37:21 -04:00
matlabbe
94c25e2017 fixed #123 2016-10-11 13:06:16 -04:00
matlabbe
b09c97169a clams: added some debug log on reading 2016-10-06 21:31:21 -04:00
matlabbe
37192422be Fixed util3d::laserScanToPointCloudRGB for 2 channels scan (added also default color param) 2016-10-05 18:11:58 -04:00
matlabbe
9e7b905c0b undistort: check nan values too 2016-10-05 13:55:02 -04:00
matlabbe
33501fdb0f max optimization error checked on link with variance <=1 instead of <1 (to make it work also when TF odom is used, for which variance of 1 is set) 2016-10-03 17:11:20 -04:00
matlabbe
6f00cba872 Added OccupancyGrid::isGridFromDepth() method for convenience 2016-10-02 16:47:22 -04:00
matlabbe
29f4734ec6 Calibration 3-steps: updated warning msg 2016-09-30 14:47:55 -04:00
matlabbe
b17e0dc26d Calibration 3-steps: fixed crash on step 3 if intrinsic parameters are not correctly loaded (empty distorsion model) 2016-09-30 14:38:45 -04:00
matlabbe
403bfc2b44 Merge branch 'kinetic-devel' of https://github.com/introlab/rtabmap 2016-09-29 12:45:21 -04:00
matlabbe
4d6cfbba20 RTABMapConfig.cmake: added find VTK if vtkGUISupportQt target is required 2016-09-29 12:40:51 -04:00
matlabbe
a1593a69a4 Enabled esport to g2o even if not built with g2o support (export doesn't need the library) 2016-09-28 16:07:01 -04:00
matlabbe
8c05ae332c Merge branch 'kinetic-devel' of https://github.com/introlab/rtabmap 2016-09-27 16:35:06 -04:00
matlabbe
7f0c49b14d Fixing QVTKWidget linker errors on Kinetic/VTK6/PCL for armhf build 2016-09-27 15:43:23 -04:00
matlabbe
b7fae1a65b SensorData: updated how compressed user_data is detected 2016-09-26 16:33:24 -04:00
matlabbe
a4dd47374e Backward compatibility: Fixed wrong image height set in SensorData::uncompressData() 2016-09-25 18:13:49 -04:00
matlabbe
4062b960c7 fixed a compilation warning 2016-09-22 14:35:37 -04:00
matlabbe
44bf3d40ad Fixed invalid controlling predicate compilation error on linux 2016-09-20 16:26:46 -04:00
matlabbe
5f85c2a7a0 Fixed missing left/right suffixes when loading stereo calibration files 2016-09-20 11:52:06 -04:00
matlabbe
3530da935b 0.11.11: changed Statistics table name to Info and added new Statistics table containing detection statistics. StatisticsToolBox can cache statistics (true by default). DatabaseViewer: new Statistics panel to see all statistics contained in the database. 2016-09-20 11:19:34 -04:00
matlabbe
a0972158dc PostProcessing, added some processEvents to see updates in progress dialog 2016-09-19 17:54:51 -04:00
matlabbe
3434b95d68 Integration of CLAMS depth calibration #114 2016-09-19 14:01:06 -04:00
matlabbe
861cc437f4 Updated Freenect2 calibration lookup names 2016-09-13 18:57:44 -04:00
matlabbe
2b2dc2be39 Fixed Windows build errors #115 2016-09-13 18:46:05 -04:00
matlabbe
acb700bd27 Added OpenNI2 and Freenect calibration #115 2016-09-13 18:26:18 -04:00
matlabbe
e5977d6157 Ignoring black pixels when creating clouds (recfification artifacts). Slightly improved depth retification speed. 2016-09-13 12:10:14 -04:00
matlabbe
44caa12fa5 CameraStereoVideo: added left and right separated video streams. Fixed issue #117 2016-09-11 12:45:12 -04:00
matlabbe
26c7078923 Tango: slight modifications of the default parameters 2016-09-10 18:45:46 -04:00
matlabbe
94a4fb4579 fixed 2 compilation warnings 2016-09-09 15:10:19 -04:00
matlabbe
d6f9f29835 Fixed list not defined error in util3d_surface.h. Updated rgbd_mapping example with Freenect2, zed and realsense options 2016-09-09 18:35:56 -04:00
matlabbe
2eb2362da8 Tango: Handling app pause/resume without having to restart mapping (OpenGL context flushed issue). 2016-09-08 11:55:44 -04:00
matlabbe
53c3981651 Tango: Fixed typo making textures not appearing... 2016-09-07 20:25:41 -04:00
matlabbe
d252b1fb13 GUI: Fixed cannot delete rtabmap.tmp.db error when closing and if database is in memory. 2016-09-07 20:15:30 -04:00
matlabbe
d3173d8533 Tango: Optimized memory for created meshes (keeping dense clouds instead of organized clouds) 2016-09-07 19:59:25 -04:00
matlabbe
4a072b3dfc Tango: Added "Adjust colors" post-processing option. Updated ICP parameters. Added "Mem/LaserScanNormalK" parameter for convenience. 2016-09-07 17:19:21 -04:00
matlabbe
ce1acd9d44 DatabaseViewer: showing normals if scans have 6 channels 2016-09-07 17:14:09 -04:00
matlabbe
ff4300d525 Added GainCompensator class. GUI/3D Rendering: added texturing option. 2016-09-07 12:15:44 -04:00
matlabbe
3b25fef852 Tango: updated manifest to version 10 2016-09-03 20:46:22 -04:00
matlabbe
91da92346d Tango: added Noise Filtering post-processing option, set RGBD/MaxLocalRetrieved to 0 (avoiding some high processing time peaks), fill depth holes up to 5 pixels 2016-09-03 20:38:27 -04:00
matlabbe
7f2c118f8d Added min polygon cluster size option (DbViewer and GUI export) 2016-09-03 18:59:43 -04:00
matlabbe
0848b03127 DBReader: set calibrated to true if database is empty (avoiding not calibrated warning) 2016-09-03 14:45:10 -04:00
matlabbe
e5074afdeb Tango: Added ICP refining option, mesh vs texture vs point cloud options, show/hide grid option, drift correction option 2016-09-02 22:37:12 -04:00
matlabbe
4bd9e4f847 OctoMap: Added occupancy threshold to constructor 2016-09-01 20:33:05 -04:00
matlabbe
717e82c09e fixed typos 2016-09-01 19:22:04 -04:00
matlabbe
d069dedf34 PostProcessing: fixed scans not uncompressed before refining 2016-09-01 18:36:55 -04:00
matlabbe
dd2f89628e cloudFromDepthRGB() iterating over depth image size instead of RGB image size. DbViewer: fixed scale of image view when depth is smaller than rgb. 2016-09-01 16:42:34 -04:00
matlabbe
87b9f30dce fixed warning ("centroid" may be not initialized)... 2016-09-01 14:55:19 -04:00
matlabbe
76298e86be CMake: set WITH_QT=OFF for android by default 2016-09-01 13:40:44 -04:00
matlabbe
aaef1ac997 Merge pull request #111 from willdzeng/master
include list in FlannIndex.h
2016-08-31 22:19:00 -04:00
Di Zeng
794ee2f562 include list in FlannIndex.h 2016-08-31 15:06:50 -07:00
Mathieu Labbe
546c66ea3c cloudFromDepth(): changed roi ratios warning to error 2016-08-31 14:15:48 -04:00
matlabbe
7a4de966d4 cloudFromDepth(): fixed roi ratios not used if one value was null. DbViewer: Added occupancy grid clouds to 3d views, add action to regenerate occupancy grids only for the current selected ids. 2016-08-31 12:43:54 -04:00
matlabbe
c404234635 OccupancyGrid: added Grid/Footprint*** parameters, templated segmentCloud() function, added Grid/ClusterRadius parameter. Parameters: fixed getDefaultParameters(group) function to correctly compare groups. 2016-08-31 12:43:54 -04:00
matlabbe
6fe7d5a856 OccupancyGrid: fixed 2d scan not transformed before creating grid 2016-08-31 12:43:54 -04:00
matlabbe
2fb71445da Added warning when requesting a path before beeing localized 2016-08-31 12:43:54 -04:00
matlabbe
79b51311bc DatabaseViewer: removed unknown grid cell filled parameter 2016-08-31 12:43:54 -04:00
matlabbe
fe6eb01404 Fixed opencv setSize assert error (RegistrationVis):
[DEBUG] (2016-08-29 10:26:03.821) RegistrationVis.cpp:460::computeTransformationImpl() kptsFrom=0
[DEBUG] (2016-08-29 10:26:03.821) RegistrationVis.cpp:461::computeTransformationImpl() kptsTo=0
OpenCV Error: Assertion failed (s >= 0) in setSize, file /home/mathieu/workspace/opencv-2.4.11/modules/core/src/matrix.cpp, line 116
terminate called after throwing an instance of 'cv::Exception'
  what():  /home/mathieu/workspace/opencv-2.4.11/modules/core/src/matrix.cpp:116: error: (-215) s >= 0 in function setSize
2016-08-31 12:43:54 -04:00
matlabbe
5542918b04 Fixed holes in 2d occupancy grids created from scans. Fixed grid map in 3D view not updated. 2016-08-31 12:43:54 -04:00
matlabbe
e93ef025a1 DatabaseViewer: added occupancy grid to 3D view 2016-08-31 12:43:54 -04:00
matlabbe
8d31b6140d CloudViewer: added occupancy grid support for PCL < 1.7.2 2016-08-31 12:43:54 -04:00
matlabbe
4e027a6515 Grid/DetectFlatObstacles default true. segmentObstaclesFromGround(): Fixed not used indices still kept in obstacles output 2016-08-31 12:43:54 -04:00
matlabbe
797f1f0f1c DatabaseViewer: added regeneration of occupancy grids action and saving back to database on close 2016-08-31 12:43:54 -04:00
matlabbe
4d8200fef3 Added "RGBD/ProximityPathMaxNeighbors" parameter 2016-08-31 12:43:54 -04:00
matlabbe
edee909324 RegistrationICP: fixed local scan transform issue 2016-08-31 12:43:54 -04:00
matlabbe
48f54cf2f2 FlannIndex: changed how detection of index rebuilt is done (to handle index that always rebuild on addPoints()). CameraImages: Fixed null scan local transform 2016-08-31 12:43:54 -04:00
matlabbe
c8cb961108 Refactored FlannIndex: Moved class into its own include file. Added radiusSearch() and buildKDtreeSingleIndex() methods. If dimensions <= 3 and float, use L2_Simple distance type. 2016-08-31 12:43:53 -04:00
matlabbe
013eba1d58 0.11.10: Database update with occupancy grid and laser scan info. Added class LaserScanInfo and OccupancyGrid (incremental 2d grid map). Gui: 2d grid and octomap are udpated using occupancy grids saved in nodes. 2016-08-31 12:43:53 -04:00
matlabbe
af02e02978 Added Occupancy class. Database SQL: added ground_cells, obstacle_cells and cell_size fields to Node table (updated Signature too). 2016-08-31 12:43:53 -04:00
matlabbe
b947bde3db ZED SDK v1.1.0: Fixed compilation errors 2016-08-31 11:37:27 -04:00
matlabbe
34b8fdfe6d Merge pull request #110 from berkaydeniz/finddc1394-fix
in FindDC1394.cmake Mac OS X based framework setup gives errror.
2016-08-31 11:07:55 -04:00
Berkay Deniz Ilhan
47e7b621ad in FindDC1394.cmake Mac OS X based framework setup gives errror. 2016-08-30 02:30:35 -04:00
Mathieu Labbe
52c7395578 fixed rgbdMatC4 not declared compilation error (bug from #108) 2016-08-28 16:06:49 -04:00
matlabbe
fb527e5df4 util2d::getDepth() fixed tmp not divided 2016-08-27 09:06:15 -04:00
matlabbe
7161756cc9 Merge pull request #108 from lesterlo/nvidia_jetson_fix
Improve Freenect2 performance
2016-08-26 09:50:22 -04:00
lesterlo
f180beb3f9 1. Add freenect2 cuda pipeline
2. Fix TegraJPEG Color problem, convert from RGB to BGR
2016-08-26 15:40:10 +08:00
matlabbe
a302a6334d Fixed #107 2016-08-24 09:02:58 -04:00
matlabbe
18b1931e7c Added occupancy grid footprintRadius parameter to clear obstacles under path 2016-08-14 14:52:42 -04:00
matlabbe
ae7436a41b Fixed bug where very long paths (over maxGraphDepth) were used for scan matching. Added "RGBD/ProximityMaxPaths" parameter (default 3) to limit the number of path comparisons for proximity detection. 2016-08-12 18:43:12 -04:00
matlabbe
a0d76eabe5 RegistrationVis: don't assert if descriptorsFrom is 0, only if kptsFrom and descriptorsFrom are non null and not equal 2016-08-12 10:59:43 -04:00
matlabbe
5557701f44 suppressing CMP0020 and CMP0043 warnings 2016-08-11 14:13:29 -04:00
matlabbe
0ccb69bc06 Fixed calibrations not loaded for bad signatures 2016-08-10 10:35:53 -04:00
matlabbe
0152941ecf MainWindow: Fixed a bug creating more error with refining with ICP in Post-Processing 2016-08-10 10:06:22 -04:00
matlabbe
28462bb2b5 Preferences/Source: fixed disabled RGBD Images source 2016-08-09 17:13:08 -04:00
matlabbe
a824b24058 Added util3d::transformLaserScan(). OdomF2F: filling local scan map field with key frame scane in odom info. DbViewer: Print database parameters in Info view. 2016-08-08 14:35:39 -04:00
matlabbe
6ef9034a67 Fixed ICP-only odometry when guess from motion is enabled 2016-08-07 20:54:56 -04:00
matlabbe
93f1ae501c Fixed disabled KDTree in Preferences when built without nonfree OpenCV module 2016-08-05 16:55:06 -04:00
matlabbe
d9b3eafc39 DatabaseViewer: cloud in 3D view is now in base frame instead of camera frame 2016-08-05 15:30:38 -04:00
matlabbe
5dd42cf925 Added r200 icon 2016-08-03 20:03:31 -04:00
matlabbe
e4c4c8c468 Added c++11 flag when RealSense is detected 2016-08-03 11:39:43 -04:00
matlabbe
72a76f6c80 Tango: Fixed computeNormals() type conversion build error #90 2016-08-01 16:00:58 -04:00
matlabbe
071670e24c Added c++11 flag for Android build (Tango) issue #90 2016-08-01 15:38:22 -04:00
matlabbe
c25c1db3da Odometry: changed isF2M() and isF2F() by getType() (following pull request https://github.com/introlab/rtabmap/pull/102) 2016-08-01 15:26:35 -04:00
matlabbe
c0cc57d1d8 Merge pull request #102 from willdzeng/master
added the type virtual function to avoid dynamic cast
2016-08-01 15:13:15 -04:00
Di Zeng
33dab87765 added the type virtual function to avoid dynamic cast 2016-07-28 11:59:24 -07:00
matlabbe
9d09c509ab Added librealsense support #100 2016-07-26 18:39:34 -04:00
matlabbe
dbb29c7661 databaseViewer: Fixed link's covariance modified when pose correction was disabled. Link: setVariance() and setInfMatrix are now private, to force re-cloning the link if we want to change these info. 2016-07-24 13:23:22 -04:00
matlabbe
1a1cf5f672 Freenect2: Fixed initRectifyMap error with custom calibration 2016-07-21 12:40:25 -04:00
matlabbe
759c917498 Octomap: changed warning log "Did not find...in cahe" to a debug log 2016-07-21 10:14:22 -04:00
matlabbe
d7b1d617ea GUI: Fixed loaded parameters not actually modified from opened database 2016-07-20 17:07:35 -04:00
matlabbe
1e47271c91 DBReader: Fixed wrong virtual inherited function name odometryProvided() -> odomProvided() 2016-07-20 16:37:32 -04:00
matlabbe
1dca6116be Fixed default parameters on init for octomap 2016-07-20 15:17:59 -04:00
matlabbe
ff59274c95 updated LICENSE year 2016-07-17 22:01:57 -04:00
matlabbe
ca6cd19fb1 Updated Copyright year and About dialog summary 2016-07-17 21:57:10 -04:00
matlabbe
be61eefdf9 Fixed build errors without octomap 2016-07-17 21:36:54 -04:00
matlabbe
cf2bb6b599 CMake: Added PCL_OMP option (default ON) to use OMP implementations of some PCL classes (#50) 2016-07-17 21:04:11 -04:00
matlabbe
d739d04232 Disable multi-arch lib by default (#97) 2016-07-17 20:12:13 -04:00
matlabbe
711ff2692c Updated default x-axis units of the figures with time stamps instead of IDs (#48). 2016-07-17 19:58:32 -04:00
matlabbe
705f4337e4 Fixed #42 2016-07-17 17:44:12 -04:00
matlabbe
237ab2be45 Projection map frame is still doing roll/pitch transformation (without z) 2016-07-17 17:06:36 -04:00
matlabbe
536136af77 Fixed octomap height when in /map frame. Preferences: added Cloud Filtering and Occupancy Grid Map subpanels to 3D Rendering 2016-07-17 16:47:06 -04:00
matlabbe
d4e5cfb548 fixed octomap ground cells removed when updating graph 2016-07-17 15:37:08 -04:00
matlabbe
b5e5e9508c fixed crash when activating octomap while mapping 2016-07-17 14:58:28 -04:00
matlabbe
f161609a24 Added octomap ground is an obstacle option 2016-07-16 10:57:59 -04:00
matlabbe
b4b7b6f455 Added Octomap visualization and export options 2016-07-15 17:46:13 -04:00
Mathieu Labbe
c24079884d Reset stuck when moving toward the goal 2016-07-11 17:40:34 -04:00
matlabbe
38c3e3600d Planning stuck detection updated: now using distance to goal 2016-07-11 17:16:11 -04:00
matlabbe
09795678ef Merge branch 'master' of github.com:introlab/rtabmap into devel 2016-07-08 19:45:00 -04:00
matlabbe
b3207d6402 PLanning: Detect if the pose is reachable from the current node before looking for the nearest one 2016-07-08 19:44:44 -04:00
matlabbe
c6439cb1b7 Merge branch 'master' of github.com:introlab/rtabmap into devel 2016-07-08 19:23:05 -04:00
matlabbe
61f6e5ff79 Using fly distance instead of path distance to update the farthest goals 2016-07-08 19:22:48 -04:00
matlabbe
4cd8705710 Fixed cloudFromDepth() method when depth image is not the same size as the calibration file. That fixes projection map created from Tango databases (where depth size != rgb size) 2016-07-08 12:47:23 -04:00
matlabbe
c8cd2545d3 fixed build without octomap 2016-07-08 00:21:36 -04:00
matlabbe
6f310ff63a util2d::getDepth(): fixed small error on depth assignation (mm) 2016-07-05 18:21:39 -04:00
matlabbe
20862f07bc RegistrationInfo: added IcpTranslation and IcpRotation members 2016-07-05 11:23:59 -04:00
matlabbe
1365eaca3a Merged master to devel 2016-07-04 15:38:28 -04:00
matlabbe
9dfc7801a0 Fixed fatal error in #91 2016-07-04 13:39:33 -04:00
matlabbe
02d4ca5c8b util3d::segmentObstaclesFromGround: added viewPoint argument (default 0,0,100) 2016-07-04 11:47:10 -04:00
matlabbe
c2a7b2f13a Odometry: Added process() with optional guess interface 2016-06-30 11:34:46 -04:00
matlabbe
4115bc416e Added OctoMap class 2016-06-28 19:00:44 -04:00
matlabbe
060a3fd47e Merge branch 'master' of github.com:introlab/rtabmap into devel 2016-06-27 16:11:08 -04:00
matlabbe
84726fa45c Update Odometry.cpp 2016-06-27 16:10:18 -04:00
matlabbe
3609c961ea Merge branch 'master' of github.com:introlab/rtabmap into devel 2016-06-27 16:08:53 -04:00
matlabbe
756e176878 Update Odometry.cpp
Odometry: Added additional debug information on dt>0 assert
2016-06-27 16:08:25 -04:00
matlabbe
1398b71b60 Merge branch 'master' of github.com:introlab/rtabmap into devel 2016-06-27 12:17:55 -04:00
matlabbe
f69ca56179 Features2D: Using 255 mask values for ORB (#89). Fixed ignored mask by FAST when called from ORB. 2016-06-27 11:54:21 -04:00
matlabbe
a310b5e864 DB: Added error when loading a database with version more recent than installed rtabmap version 2016-06-25 13:28:26 -04:00
matlabbe
517bfa5272 OdometryF2M: updated how local scan map is updated 2016-06-25 13:18:09 -04:00
matlabbe
ca95c9de97 Changed an OpenCV_LIBS to OpenCV_LIBRARIES 2016-06-24 21:00:12 -04:00
matlabbe
37c269bc0b fixed a warning 2016-06-24 19:23:11 -04:00
matlabbe
e90c97f8a4 ZED driver: added option to use visual odometry approach from zed sdk. RtabmapThread: fixed thread state change on new map trigger on Odometry init (variance=9999). Odometry: on init, verify that the first frame is ok before sending first pose. Parameters: Mem/SaveDepth16Format is now false by default 2016-06-24 18:49:34 -04:00
matlabbe
af6e17fce8 GUI: Added color code for odometry features 2016-06-24 16:02:27 -04:00
matlabbe
b86352bfc0 merged master to devel 2016-06-23 15:44:24 -04:00
matlabbe
f03a1b50ef Fixed build with ZED SDK 1.0.0... cmake find_package ZED version 1 (#85) 2016-06-23 15:41:32 -04:00
matlabbe
70da8d26c0 Fixed build with ZED SDK 1.0.0 (#85) 2016-06-23 15:40:11 -04:00
matlabbe
333c7433e8 Merge branch 'master' of https://github.com/introlab/rtabmap into devel 2016-06-23 11:27:58 -04:00
matlabbe
f2d48cb894 Fixed ICP-only registration with already provided guess (no need to do visual guess, as the guess can be already good) 2016-06-23 11:08:20 -04:00
matlabbe
22766e958f Update VWDictionary.cpp
Fixed "HAVE_OPENCV_CUDAFEATURES2D" build error of https://github.com/introlab/rtabmap/issues/85
2016-06-22 19:28:22 -04:00
matlabbe
42c3186a53 Memory::computeTransform(): fixed null guess sent to pure ICP registration 2016-06-21 16:42:21 -04:00
matlabbe
530919c531 CameraThread: fixed scan from depth max points with multi-camera 2016-06-21 11:36:50 -04:00
matlabbe
0ec39e3c77 DBReader now inherits from Camera (so that CameraThread's post processing stuff can be used with a database stream) 2016-06-21 11:22:24 -04:00
matlabbe
cdddb1209e DBReader: added camera selection 2016-06-20 10:50:01 -04:00
matlabbe
62db5370aa CloudViewer: Added updateCameraFrustum() method (multi-cameras supported) 2016-06-19 18:33:36 -04:00
matlabbe
ab991c2a7d CameraModel::scaled() scale Tx an Ty too 2016-06-17 16:47:02 -04:00
matlabbe
d03b54d95a Parameters: removed trailing 0 for double/float parameters, to avoid serializing with them (so that we don't have the 0.0 != 0 when loading parameters from database) 2016-06-16 15:34:27 -04:00
matlabbe
62a982ef9f DbDriverSqlite3: Fixed multi-camera calibration loading error with version >= 0.11.2 2016-06-16 14:57:55 -04:00
matlabbe
798c3cb373 Registration: added warning when GuessFlowSize is set and multi-camera is detected instead of crashing on an assert 2016-06-15 18:13:11 -04:00
matlabbe
7f55e2c9bb Merge branch 'master' of github.com:introlab/rtabmap into devel 2016-06-15 16:39:25 -04:00
matlabbe
8e76de7d34 Fixed GTSAM/Eigen include dir 2016-06-15 15:48:56 -04:00
matlabbe
ac284ab067 GUI: fixed odometry visibility flickering 2016-06-15 14:18:26 -04:00
matlabbe
95f9304f4f CameraStereo: fixed rectify=false ignored 2016-06-15 11:36:37 -04:00
matlabbe
7b733686cb Updated CameraVideo and CameraStereoVideo constructor interface with USB 2016-06-15 11:30:05 -04:00
matlabbe
bdafb9a3f1 Merge branch 'master' of github.com:introlab/rtabmap into devel 2016-06-14 11:56:22 -04:00
matlabbe
abd376a44c segmentObstaclesFromGround() fixed identical ground and obstacles indices 2016-06-14 11:55:58 -04:00
matlabbe
38a7993a9b Database: added "parameters" field in Statistics table. GUI: detecting if parameters in database are different from the Preferences, if so ask user to update them. 2016-06-13 17:34:17 -04:00
matlabbe
3edb133727 Increased default Stereo/MaxDisparity to 128 2016-06-13 14:37:19 -04:00
matlabbe
84dd258777 Added "Odom/AligWithGround" parameter. Added util3d::extractPlane(). 2016-06-12 21:45:22 -04:00
matlabbe
543b8df045 MainWindow: Added statistics about how much size the created clouds take in RAM. Avoid caching data on small movements. Export: Fixed meshing checkbox and pipeline combo box not saved/loaded. PreferencesDialog: Added option to disable caching the point clouds. computeNormals(): added viewpoint parameter. mls(): making sure that all returned normals are normalized. 2016-06-12 17:53:35 -04:00
matlabbe
cb7c76889d API achange (0.11.8): computeNormals returns only pcl::Normal cloud, not pcl::PointNormal or pcl::PointXYZRGBNormal types. MainWindow: Normals are not kept in cache to save RAM. ProgressDialog: check if auto-close is still checked when close() slot is called. 2016-06-12 13:51:49 -04:00
matlabbe
9f296c67b2 GUI: Added more parameters for 3D projection grid map 2016-06-10 20:12:13 -04:00
matlabbe
4a3f490814 Added Reg/Force2D compatibility name for Reg/Force3DoF 2016-06-09 15:49:17 -04:00
matlabbe
cbf348fafa labels can be saved in localization mode 2016-06-08 18:19:51 -04:00
matlabbe
e205883de5 Export: set 0 voxel size by default 2016-06-08 11:53:25 -04:00
matlabbe
ce04336648 fixed cmake warning, removed a .DS_Store from repository 2016-06-04 16:21:00 -04:00
matlabbe
a8bf7e5d5f Fixed Qt5 plugins release. Zed driver: sdded 2 seconds delay before sending grab error. 2016-06-04 15:17:13 -04:00
matlabbe
69e1973544 Update MainWindow.cpp 2016-06-03 15:06:18 -04:00
matlabbe
2f817568e2 MainWindow: Don't show an error if a created cloud is empty 2016-06-02 17:52:22 -04:00
matlabbe
d9611f784c Added ZED parameters 2016-06-02 17:27:12 -04:00
265 changed files with 27733 additions and 9889 deletions

View File

@@ -18,12 +18,14 @@ install:
- sudo sh -c 'echo "deb http://packages.ros.org/ros/ubuntu trusty main" > /etc/apt/sources.list.d/ros-latest.list' - sudo sh -c 'echo "deb http://packages.ros.org/ros/ubuntu trusty main" > /etc/apt/sources.list.d/ros-latest.list'
- wget http://packages.ros.org/ros.key -O - | sudo apt-key add - - wget http://packages.ros.org/ros.key -O - | sudo apt-key add -
- sudo apt-get update - sudo apt-get update
- sudo apt-get -y install libpcl-1.7-all libfreenect-dev - sudo apt-get -y install libpcl-1.7-all libfreenect-dev ros-indigo-libg2o ros-indigo-octomap libopenni2-dev
script: script:
- source /opt/ros/indigo/setup.bash
- mkdir -p build && cd build - mkdir -p build && cd build
- cmake .. - cmake ..
- make - make
notifications: notifications:
email: false email:
- matlabbe@gmail.com

View File

@@ -6,9 +6,10 @@ SET(PROJECT_PREFIX rtabmap)
# Catkin doesn't support multiarch library path, # Catkin doesn't support multiarch library path,
# fix to "lib" if not set by user. # fix to "lib" if not set by user.
#IF(NOT DEFINED CMAKE_INSTALL_LIBDIR) OPTION(MULTI_ARCH "Activate multi-arch lib directory (debian)" OFF)
# set(CMAKE_INSTALL_LIBDIR "lib") IF(NOT MULTI_ARCH AND NOT DEFINED CMAKE_INSTALL_LIBDIR)
#ENDIF(NOT DEFINED CMAKE_INSTALL_LIBDIR) set(CMAKE_INSTALL_LIBDIR "lib")
ENDIF(NOT MULTI_ARCH AND NOT DEFINED CMAKE_INSTALL_LIBDIR)
INCLUDE(GNUInstallDirs) INCLUDE(GNUInstallDirs)
@@ -20,7 +21,7 @@ SET(CMAKE_MODULE_PATH "${PROJECT_SOURCE_DIR}/cmake_modules")
####################### #######################
SET(RTABMAP_MAJOR_VERSION 0) SET(RTABMAP_MAJOR_VERSION 0)
SET(RTABMAP_MINOR_VERSION 11) SET(RTABMAP_MINOR_VERSION 11)
SET(RTABMAP_PATCH_VERSION 7) SET(RTABMAP_PATCH_VERSION 13)
SET(RTABMAP_VERSION SET(RTABMAP_VERSION
${RTABMAP_MAJOR_VERSION}.${RTABMAP_MINOR_VERSION}.${RTABMAP_PATCH_VERSION}) ${RTABMAP_MAJOR_VERSION}.${RTABMAP_MINOR_VERSION}.${RTABMAP_PATCH_VERSION})
@@ -52,6 +53,13 @@ ELSE ()
ADD_DEFINITIONS("-Wno-unknown-pragmas") ADD_DEFINITIONS("-Wno-unknown-pragmas")
ENDIF() ENDIF()
if(POLICY CMP0020)
cmake_policy(SET CMP0020 OLD)
endif()
if(POLICY CMP0043)
cmake_policy(SET CMP0043 OLD)
endif()
IF(MINGW) IF(MINGW)
# Hide the --enable-auto-import warning # Hide the --enable-auto-import warning
SET(CMAKE_EXE_LINKER_FLAGS "-Wl,--enable-auto-import") SET(CMAKE_EXE_LINKER_FLAGS "-Wl,--enable-auto-import")
@@ -124,8 +132,11 @@ OPTION(BUILD_TOOLS "Build tools" ON)
OPTION(BUILD_EXAMPLES "Build examples" ON) OPTION(BUILD_EXAMPLES "Build examples" ON)
####### DEPENDENCIES ####### ####### DEPENDENCIES #######
IF(ANDROID)
option(WITH_QT "Include Qt support" OFF)
ELSE()
option(WITH_QT "Include Qt support" ON) option(WITH_QT "Include Qt support" ON)
ENDIF()
option(WITH_FREENECT "Include Freenect support" ON) option(WITH_FREENECT "Include Freenect support" ON)
option(WITH_FREENECT2 "Include Freenect2 support" ON) option(WITH_FREENECT2 "Include Freenect2 support" ON)
option(WITH_OPENNI2 "Include OpenNI2 support" ON) option(WITH_OPENNI2 "Include OpenNI2 support" ON)
@@ -137,6 +148,9 @@ option(WITH_VERTIGO "Include Vertigo support" ON)
option(WITH_CVSBA "Include cvsba support" ON) option(WITH_CVSBA "Include cvsba support" ON)
option(WITH_FLYCAPTURE2 "Include FlyCapture2/Triclops support" ON) option(WITH_FLYCAPTURE2 "Include FlyCapture2/Triclops support" ON)
option(WITH_ZED "Include ZED sdk support" ON) option(WITH_ZED "Include ZED sdk support" ON)
option(WITH_REALSENSE "Include RealSense support" ON)
option(WITH_OCTOMAP "Include Octomap support" ON)
option(PCL_OMP "With PCL OMP implementations" ON)
FIND_PACKAGE(OpenCV REQUIRED QUIET) FIND_PACKAGE(OpenCV REQUIRED QUIET)
FIND_PACKAGE(PCL 1.7 REQUIRED QUIET) FIND_PACKAGE(PCL 1.7 REQUIRED QUIET)
@@ -156,6 +170,9 @@ if(OPENMP_FOUND)
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${OpenMP_C_FLAGS}") set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${OpenMP_C_FLAGS}")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${OpenMP_CXX_FLAGS}") set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${OpenMP_CXX_FLAGS}")
message (STATUS "Found OpenMP") message (STATUS "Found OpenMP")
if(PCL_OMP)
add_definitions(-DPCL_OMP)
endif(PCL_OMP)
else(OPENMP_FOUND) else(OPENMP_FOUND)
message (STATUS "Not found OpenMP") message (STATUS "Not found OpenMP")
endif() endif()
@@ -170,6 +187,7 @@ IF(ZLIB_FOUND)
MESSAGE(STATUS "Found ZLIB: ${ZLIB_INCLUDE_DIRS}") MESSAGE(STATUS "Found ZLIB: ${ZLIB_INCLUDE_DIRS}")
ENDIF(ZLIB_FOUND) ENDIF(ZLIB_FOUND)
SET(ADD_VTK_GUI_SUPPORT_QT_TO_CONF FALSE)
IF(WITH_QT) IF(WITH_QT)
FIND_PACKAGE(VTK) FIND_PACKAGE(VTK)
IF(NOT VTK_FOUND) IF(NOT VTK_FOUND)
@@ -179,7 +197,10 @@ IF(WITH_QT)
# If Qt is here, the GUI will be built # If Qt is here, the GUI will be built
# look for Qt5 (if vtk>5 is installed) before Qt4 # look for Qt5 (if vtk>5 is installed) before Qt4
IF("${VTK_MAJOR_VERSION}" GREATER 5) IF("${VTK_MAJOR_VERSION}" GREATER 5)
FIND_PACKAGE(Qt5 COMPONENTS Widgets Core Gui Svg QUIET) FIND_PACKAGE(Qt5 COMPONENTS Widgets Core Gui QUIET)
IF(Qt5_FOUND)
FIND_PACKAGE(Qt5 COMPONENTS Widgets Core Gui Svg)
ENDIF(Qt5_FOUND)
ENDIF("${VTK_MAJOR_VERSION}" GREATER 5) ENDIF("${VTK_MAJOR_VERSION}" GREATER 5)
IF(NOT Qt5_FOUND) IF(NOT Qt5_FOUND)
@@ -189,7 +210,13 @@ IF(WITH_QT)
IF(QT4_FOUND OR Qt5_FOUND) IF(QT4_FOUND OR Qt5_FOUND)
IF("${VTK_MAJOR_VERSION}" EQUAL 5) IF("${VTK_MAJOR_VERSION}" EQUAL 5)
FIND_PACKAGE(QVTK REQUIRED) # only for VTK 5 FIND_PACKAGE(QVTK REQUIRED) # only for VTK 5
ENDIF("${VTK_MAJOR_VERSION}" EQUAL 5) ELSE()
list(FIND PCL_LIBRARIES vtkGUISupportQt value)
IF(value EQUAL -1)
SET(PCL_LIBRARIES "${PCL_LIBRARIES};vtkGUISupportQt")
SET(ADD_VTK_GUI_SUPPORT_QT_TO_CONF TRUE)
ENDIF(value EQUAL -1)
ENDIF()
ENDIF(QT4_FOUND OR Qt5_FOUND) ENDIF(QT4_FOUND OR Qt5_FOUND)
ENDIF(WITH_QT) ENDIF(WITH_QT)
@@ -207,6 +234,14 @@ IF(WITH_FREENECT2)
SET(freenect2_INCLUDE_DIRS ${freenect2_INCLUDE_DIR}) SET(freenect2_INCLUDE_DIRS ${freenect2_INCLUDE_DIR})
ENDIF(NOT freenect2_INCLUDE_DIRS) ENDIF(NOT freenect2_INCLUDE_DIRS)
MESSAGE(STATUS "Found freenect2: ${freenect2_INCLUDE_DIRS}") MESSAGE(STATUS "Found freenect2: ${freenect2_INCLUDE_DIRS}")
# Explicitly link to OpenCL (in case of CUDA installed)
FIND_PACKAGE(OpenCL QUIET)
IF(OpenCL_FOUND)
SET(freenect2_LIBRARIES
${OpenCL_LIBRARIES}
${freenect2_LIBRARIES}
)
ENDIF(OpenCL_FOUND)
ENDIF(freenect2_FOUND) ENDIF(freenect2_FOUND)
ENDIF(WITH_FREENECT2) ENDIF(WITH_FREENECT2)
@@ -264,7 +299,7 @@ IF(WITH_ZED)
LINK_DIRECTORIES( ${LINK_DIRECTORIES} ${ZED_LIBRARY_DIR}) LINK_DIRECTORIES( ${LINK_DIRECTORIES} ${ZED_LIBRARY_DIR})
ENDIF(ZED_LIBRARIES AND ZED_INCLUDE_DIRS) ENDIF(ZED_LIBRARIES AND ZED_INCLUDE_DIRS)
ELSE() # Linux ELSE() # Linux
find_package(ZED 0.9 QUIET) find_package(ZED 1 QUIET)
ENDIF(WIN32) ENDIF(WIN32)
IF(ZED_FOUND) IF(ZED_FOUND)
@@ -279,7 +314,21 @@ IF(WITH_ZED)
ENDIF(ZED_FOUND) ENDIF(ZED_FOUND)
ENDIF(WITH_ZED) ENDIF(WITH_ZED)
IF(G2O_FOUND OR GTSAM_FOUND OR ZED_FOUND) IF(WITH_REALSENSE)
FIND_PACKAGE(RealSense QUIET)
IF(RealSense_FOUND)
MESSAGE(STATUS "Found RealSense: ${RealSense_INCLUDE_DIRS}")
ENDIF(RealSense_FOUND)
ENDIF(WITH_REALSENSE)
IF(WITH_OCTOMAP)
FIND_PACKAGE(OCTOMAP QUIET)
IF(OCTOMAP_FOUND)
MESSAGE(STATUS "Found octomap: ${OCTOMAP_INCLUDE_DIRS}")
ENDIF(OCTOMAP_FOUND)
ENDIF(WITH_OCTOMAP)
IF(G2O_FOUND OR GTSAM_FOUND OR ZED_FOUND OR ANDROID OR RealSense_FOUND)
#Newest versions require std11 #Newest versions require std11
IF(NOT MSVC) IF(NOT MSVC)
include(CheckCXXCompilerFlag) include(CheckCXXCompilerFlag)
@@ -293,7 +342,7 @@ IF(G2O_FOUND OR GTSAM_FOUND OR ZED_FOUND)
message(STATUS "The compiler ${CMAKE_CXX_COMPILER} has no C++11 support. Please use a different C++ compiler if you want to use g2o or gtsam (set \"-DWITH_G2O=OFF -DWITH_GTSAM=OFF\" to build without g2o and gtsam).") message(STATUS "The compiler ${CMAKE_CXX_COMPILER} has no C++11 support. Please use a different C++ compiler if you want to use g2o or gtsam (set \"-DWITH_G2O=OFF -DWITH_GTSAM=OFF\" to build without g2o and gtsam).")
ENDIF() ENDIF()
ENDIF() ENDIF()
ENDIF(G2O_FOUND OR GTSAM_FOUND OR ZED_FOUND) ENDIF(G2O_FOUND OR GTSAM_FOUND OR ZED_FOUND OR ANDROID OR RealSense_FOUND)
####### OSX BUNDLE CMAKE_INSTALL_PREFIX ####### ####### OSX BUNDLE CMAKE_INSTALL_PREFIX #######
IF(APPLE AND BUILD_AS_BUNDLE) IF(APPLE AND BUILD_AS_BUNDLE)
@@ -383,6 +432,22 @@ IF(NOT ZED_FOUND)
ELSE() ELSE()
SET(CONF_DEPENDENCIES ${CONF_DEPENDENCIES} ${ZED_LIBRARIES} ${CUDA_LIBRARIES}) SET(CONF_DEPENDENCIES ${CONF_DEPENDENCIES} ${ZED_LIBRARIES} ${CUDA_LIBRARIES})
ENDIF() ENDIF()
IF(NOT RealSense_FOUND)
SET(REALSENSE "//")
ELSE()
SET(CONF_DEPENDENCIES ${CONF_DEPENDENCIES} ${RealSense_LIBRARIES})
ENDIF()
IF(NOT OCTOMAP_FOUND)
SET(OCTOMAP "//")
ELSE()
SET(CONF_DEPENDENCIES ${CONF_DEPENDENCIES} ${OCTOMAP_LIBRARIES})
ENDIF()
IF(ADD_VTK_GUI_SUPPORT_QT_TO_CONF)
SET(CONF_VTK_QT true)
SET(CONF_DEPENDENCIES ${CONF_DEPENDENCIES} vtkGUISupportQt)
ELSE()
SET(CONF_VTK_QT false)
ENDIF()
IF(NOT (OpenCV_FOUND AND OpenCV_VERSION_MAJOR EQUAL 3)) IF(NOT (OpenCV_FOUND AND OpenCV_VERSION_MAJOR EQUAL 3))
SET(OPENCV3 "//") SET(OPENCV3 "//")
ENDIF(NOT (OpenCV_FOUND AND OpenCV_VERSION_MAJOR EQUAL 3)) ENDIF(NOT (OpenCV_FOUND AND OpenCV_VERSION_MAJOR EQUAL 3))
@@ -669,6 +734,22 @@ ELSE()
MESSAGE(STATUS " With ZED = NO (ZED sdk not found)") MESSAGE(STATUS " With ZED = NO (ZED sdk not found)")
ENDIF() ENDIF()
IF(RealSense_FOUND)
MESSAGE(STATUS " With RealSense = YES (License: Apache-2)")
ELSEIF(NOT WITH_REALSENSE)
MESSAGE(STATUS " With RealSense = NO (WITH_REALSENSE=OFF)")
ELSE()
MESSAGE(STATUS " With RealSense = NO (librealsense not found)")
ENDIF()
IF(OCTOMAP_FOUND)
MESSAGE(STATUS " With OCTOMAP = YES (License: BSD)")
ELSEIF(NOT WITH_OCTOMAP)
MESSAGE(STATUS " With OCTOMAP = NO (WITH_OCTOMAP=OFF)")
ELSE()
MESSAGE(STATUS " With OCTOMAP = NO (octomap not found)")
ENDIF()
IF(QT4_FOUND) IF(QT4_FOUND)
MESSAGE(STATUS " With Qt4 = YES (License: Open Source or Commercial)") MESSAGE(STATUS " With Qt4 = YES (License: Open Source or Commercial)")
ELSEIF(Qt5_FOUND) ELSEIF(Qt5_FOUND)

View File

@@ -1,4 +1,4 @@
Copyright (c) 2010-2015, Mathieu Labbe - IntRoLab - Universite de Sherbrooke Copyright (c) 2010-2016, Mathieu Labbe - IntRoLab - Universite de Sherbrooke
All rights reserved. All rights reserved.
Redistribution and use in source and binary forms, with or without Redistribution and use in source and binary forms, with or without

View File

@@ -106,14 +106,14 @@ else
end end
ylabel('Time (s)') ylabel('Time (s)')
xlabel('Node indexes') xlabel('Node indexes')
meanTime = mean(LogF(:,1))*1000 meanTimeMS = mean(LogF(:,1))*1000
plot([1 length(LogF(:,1))], [0.7 0.7], 'r') plot([1 length(LogF(:,1))], [0.7 0.7], 'r')
plot([1 length(LogF(:,1))], [1 1], 'k') plot([1 length(LogF(:,1))], [1 1], 'k')
%plot([1 length(LogF(:,1))], [350 350], 'r') %plot([1 length(LogF(:,1))], [350 350], 'r')
%legend('Processing time', 'Time limit')%, 'Acquisition rate (1 Hz)') %legend('Processing time', 'Time limit')%, 'Acquisition rate (1 Hz)')
%title('Processing time') %title('Processing time')
maxTime = max(sum(LogF(:,2:7),2)+LogF(:,17)) maxTimeMS = max(sum(LogF(:,2:7),2)+LogF(:,17))*1000
maxDict = max(LogI(:, 6)) maxDict = max(LogI(:, 6))
maxWM = max(LogI(:,7)) maxWM = max(LogI(:,7))
%% %%

View File

@@ -62,6 +62,9 @@ if(@CONF_WITH_GUI@)
endif(@CONF_WITH_GUI@) endif(@CONF_WITH_GUI@)
# Dependencies # Dependencies
if(@CONF_VTK_QT@)
find_package(VTK COMPONENTS vtkGUISupportQt NO_MODULE) # to define vtkGUISupportQt target
endif(@CONF_VTK_QT@)
set(RTABMap_LIBRARIES ${RTABMap_LIBRARIES} @CONF_DEPENDENCIES@) set(RTABMap_LIBRARIES ${RTABMap_LIBRARIES} @CONF_DEPENDENCIES@)
#backward compatibilities #backward compatibilities

View File

@@ -50,6 +50,8 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
@DC1394@#define RTABMAP_DC1394 @DC1394@#define RTABMAP_DC1394
@FLYCAPTURE2@#define RTABMAP_FLYCAPTURE2 @FLYCAPTURE2@#define RTABMAP_FLYCAPTURE2
@ZED@#define RTABMAP_ZED @ZED@#define RTABMAP_ZED
@REALSENSE@#define RTABMAP_REALSENSE
@OCTOMAP@#define RTABMAP_OCTOMAP
#endif /* VERSION_H_ */ #endif /* VERSION_H_ */

BIN
app/.DS_Store vendored

Binary file not shown.

View File

@@ -2,7 +2,7 @@
<!-- BEGIN_INCLUDE(manifest) --> <!-- BEGIN_INCLUDE(manifest) -->
<manifest xmlns:android="http://schemas.android.com/apk/res/android" <manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.introlab.rtabmap" package="com.introlab.rtabmap"
android:versionCode="9" android:versionCode="29"
android:versionName="@RTABMAP_VERSION@"> android:versionName="@RTABMAP_VERSION@">
<uses-permission android:name="android.permission.CAMERA" /> <uses-permission android:name="android.permission.CAMERA" />
@@ -11,7 +11,6 @@
<uses-permission android:name="android.permission.READ_FRAME_BUFFER" /> <uses-permission android:name="android.permission.READ_FRAME_BUFFER" />
<uses-permission android:name="android.permission.ACCESS_SURFACE_FLINGER" /> <uses-permission android:name="android.permission.ACCESS_SURFACE_FLINGER" />
<uses-feature android:glEsVersion="0x00020000" /> <uses-feature android:glEsVersion="0x00020000" />
<uses-library android:name="com.projecttango.libtango_device2" android:required="true" />
<!-- This is the platform API where NativeActivity was introduced. --> <!-- This is the platform API where NativeActivity was introduced. -->
<uses-sdk android:minSdkVersion="17" /> <uses-sdk android:minSdkVersion="17" />
@@ -20,13 +19,15 @@
<application <application
android:label="@string/app_name" android:label="@string/app_name"
android:icon="@drawable/ic_launcher"> android:icon="@drawable/ic_launcher">
<uses-library android:name="com.projecttango.libtango_device2" android:required="true" />
<!-- Our activity is the built-in NativeActivity framework class. <!-- Our activity is the built-in NativeActivity framework class.
This will take care of integrating with our NDK code. --> This will take care of integrating with our NDK code. -->
<activity android:name="RTABMapActivity" <activity android:name="RTABMapActivity"
android:label="@string/app_name" android:label="@string/app_name"
android:launchMode="singleTask" android:launchMode="singleTask"
android:screenOrientation="nosensor"> android:screenOrientation="landscape">
<!-- Tell NativeActivity the name of our .so --> <!-- Tell NativeActivity the name of our .so -->
<meta-data android:name="android.app.lib_name" <meta-data android:name="android.app.lib_name"
android:value="NativeRTABMap" /> android:value="NativeRTABMap" />

View File

@@ -29,22 +29,24 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include "util.h" #include "util.h"
#include "rtabmap/utilite/ULogger.h" #include "rtabmap/utilite/ULogger.h"
#include "rtabmap/core/util3d_transforms.h" #include "rtabmap/core/util3d_transforms.h"
#include "rtabmap/core/util2d.h"
#include "rtabmap/core/OdometryEvent.h" #include "rtabmap/core/OdometryEvent.h"
#include "rtabmap/core/util2d.h"
#include <tango_client_api.h> #include <tango_client_api.h>
#include <tango_support_api.h>
namespace rtabmap { namespace rtabmap {
#define nullptr 0 #define nullptr 0
const int kVersionStringLength = 128; const int kVersionStringLength = 128;
const int holeSize = 10; const int holeSize = 5;
const float maxDepthError = 0.10; const float maxDepthError = 0.10;
const int scanDownsampling = 10;
// Callbacks // Callbacks
void onPointCloudAvailableRouter(void* context, const TangoXYZij* xyz_ij) void onPointCloudAvailableRouter(void* context, const TangoPointCloud* point_cloud)
{ {
CameraTango* app = static_cast<CameraTango*>(context); CameraTango* app = static_cast<CameraTango*>(context);
app->cloudReceived(cv::Mat(1, xyz_ij->xyz_count, CV_32FC3, xyz_ij->xyz[0]), xyz_ij->timestamp); app->cloudReceived(cv::Mat(1, point_cloud->num_points, CV_32FC4, point_cloud->points[0]), point_cloud->timestamp);
} }
void onFrameAvailableRouter(void* context, TangoCameraId id, const TangoImageBuffer* color) void onFrameAvailableRouter(void* context, TangoCameraId id, const TangoImageBuffer* color)
@@ -76,8 +78,11 @@ void onFrameAvailableRouter(void* context, TangoCameraId id, const TangoImageBuf
void onPoseAvailableRouter(void* context, const TangoPoseData* pose) void onPoseAvailableRouter(void* context, const TangoPoseData* pose)
{ {
CameraTango* app = static_cast<CameraTango*>(context); if(pose->status_code == TANGO_POSE_VALID)
app->poseReceived(app->tangoPoseToTransform(pose, true)); {
CameraTango* app = static_cast<CameraTango*>(context);
app->poseReceived(app->tangoPoseToTransform(pose));
}
} }
void onTangoEventAvailableRouter(void* context, const TangoEvent* event) void onTangoEventAvailableRouter(void* context, const TangoEvent* event)
@@ -86,18 +91,11 @@ void onTangoEventAvailableRouter(void* context, const TangoEvent* event)
app->tangoEventReceived(event->type, event->event_key, event->event_value); app->tangoEventReceived(event->type, event->event_key, event->event_value);
} }
// In OpenGL, axes are x->right, y->up and z->outScreen
// Image is x->right, y->down and z->inScreen
static rtabmap::Transform opticalRotation(
1.0f, 0.0f, 0.0f, 0.0f,
0.0f, -1.0f, 0.0f, 0.0f,
0.0f, 0.0f, -1.0f, 0.0f);
////////////////////////////// //////////////////////////////
// CameraTango // CameraTango
////////////////////////////// //////////////////////////////
CameraTango::CameraTango(int decimation, bool autoExposure) : CameraTango::CameraTango(int decimation, bool autoExposure) :
Camera(0, opticalRotation), Camera(0),
tango_config_(0), tango_config_(0),
firstFrame_(true), firstFrame_(true),
decimation_(decimation), decimation_(decimation),
@@ -118,6 +116,8 @@ bool CameraTango::init(const std::string & calibrationFolder, const std::string
{ {
close(); close();
TangoSupport_initializeLibrary();
// Connect to Tango // Connect to Tango
LOGI("NativeRTABMap: Setup tango config"); LOGI("NativeRTABMap: Setup tango config");
tango_config_ = TangoService_getConfig(TANGO_CONFIG_DEFAULT); tango_config_ = TangoService_getConfig(TANGO_CONFIG_DEFAULT);
@@ -178,6 +178,14 @@ bool CameraTango::init(const std::string & calibrationFolder, const std::string
return false; return false;
} }
// Need to specify the depth_mode as XYZC.
ret = TangoConfig_setInt32(tango_config_, "config_depth_mode", TANGO_POINTCLOUD_XYZC);
if (ret != TANGO_SUCCESS)
{
LOGE("Failed to set 'depth_mode' configuration flag with error code: %d", ret);
return false;
}
// Note that it's super important for AR applications that we enable low // Note that it's super important for AR applications that we enable low
// latency imu integration so that we have pose information available as // latency imu integration so that we have pose information available as
// quickly as possible. Without setting this flag, you'll often receive // quickly as possible. Without setting this flag, you'll often receive
@@ -189,6 +197,19 @@ bool CameraTango::init(const std::string & calibrationFolder, const std::string
return false; return false;
} }
// Drift correction allows motion tracking to recover after it loses tracking.
//
// The drift corrected pose is is available through the frame pair with
// base frame AREA_DESCRIPTION and target frame DEVICE.
/*ret = TangoConfig_setBool(tango_config_, "config_enable_drift_correction", true);
if (ret != TANGO_SUCCESS) {
LOGE(
"NativeRTABMap: enabling config_enable_drift_correction "
"failed with error code: %d",
ret);
return false;
}*/
// Get TangoCore version string from service. // Get TangoCore version string from service.
char tango_core_version[kVersionStringLength]; char tango_core_version[kVersionStringLength];
ret = TangoConfig_getString(tango_config_, "tango_service_library_version", tango_core_version, kVersionStringLength); ret = TangoConfig_getString(tango_config_, "tango_service_library_version", tango_core_version, kVersionStringLength);
@@ -204,7 +225,7 @@ bool CameraTango::init(const std::string & calibrationFolder, const std::string
LOGI("NativeRTABMap: Setup callbacks"); LOGI("NativeRTABMap: Setup callbacks");
// Attach the OnXYZijAvailable callback. // Attach the OnXYZijAvailable callback.
// The callback will be called after the service is connected. // The callback will be called after the service is connected.
ret = TangoService_connectOnXYZijAvailable(onPointCloudAvailableRouter); ret = TangoService_connectOnPointCloudAvailable(onPointCloudAvailableRouter);
if (ret != TANGO_SUCCESS) if (ret != TANGO_SUCCESS)
{ {
LOGE("NativeRTABMap: Failed to connect to point cloud callback with error code: %d", ret); LOGE("NativeRTABMap: Failed to connect to point cloud callback with error code: %d", ret);
@@ -221,6 +242,7 @@ bool CameraTango::init(const std::string & calibrationFolder, const std::string
// Attach the onPoseAvailable callback. // Attach the onPoseAvailable callback.
// The callback will be called after the service is connected. // The callback will be called after the service is connected.
TangoCoordinateFramePair pair; TangoCoordinateFramePair pair;
//pair.base = TANGO_COORDINATE_FRAME_AREA_DESCRIPTION; // drift correction is enabled
pair.base = TANGO_COORDINATE_FRAME_START_OF_SERVICE; pair.base = TANGO_COORDINATE_FRAME_START_OF_SERVICE;
pair.target = TANGO_COORDINATE_FRAME_DEVICE; pair.target = TANGO_COORDINATE_FRAME_DEVICE;
ret = TangoService_connectOnPoseAvailable(1, &pair, onPoseAvailableRouter); ret = TangoService_connectOnPoseAvailable(1, &pair, onPoseAvailableRouter);
@@ -257,34 +279,16 @@ bool CameraTango::init(const std::string & calibrationFolder, const std::string
// as well. We use timestamp 0.0 and the target frame pair to get the // as well. We use timestamp 0.0 and the target frame pair to get the
// extrinsics from the sensors. // extrinsics from the sensors.
// //
// Get device with respect to imu transformation matrix. // Get color camera with respect to device transformation matrix.
frame_pair.base = TANGO_COORDINATE_FRAME_IMU; frame_pair.base = TANGO_COORDINATE_FRAME_DEVICE;
frame_pair.target = TANGO_COORDINATE_FRAME_DEVICE; frame_pair.target = TANGO_COORDINATE_FRAME_CAMERA_COLOR;
ret = TangoService_getPoseAtTime(0.0, frame_pair, &pose_data);
if (ret != TANGO_SUCCESS)
{
LOGE("NativeRTABMap: Failed to get transform between the IMU frame and device frames");
return false;
}
imuTDevice_ = rtabmap::Transform(
pose_data.translation[0],
pose_data.translation[1],
pose_data.translation[2],
pose_data.orientation[0],
pose_data.orientation[1],
pose_data.orientation[2],
pose_data.orientation[3]);
// Get color camera with respect to imu transformation matrix.
frame_pair.base = TANGO_COORDINATE_FRAME_IMU;
frame_pair.target = TANGO_COORDINATE_FRAME_CAMERA_DEPTH;
ret = TangoService_getPoseAtTime(0.0, frame_pair, &pose_data); ret = TangoService_getPoseAtTime(0.0, frame_pair, &pose_data);
if (ret != TANGO_SUCCESS) if (ret != TANGO_SUCCESS)
{ {
LOGE("NativeRTABMap: Failed to get transform between the color camera frame and device frames"); LOGE("NativeRTABMap: Failed to get transform between the color camera frame and device frames");
return false; return false;
} }
imuTDepthCamera_ = rtabmap::Transform( deviceTColorCamera_ = rtabmap::Transform(
pose_data.translation[0], pose_data.translation[0],
pose_data.translation[1], pose_data.translation[1],
pose_data.translation[2], pose_data.translation[2],
@@ -293,8 +297,6 @@ bool CameraTango::init(const std::string & calibrationFolder, const std::string
pose_data.orientation[2], pose_data.orientation[2],
pose_data.orientation[3]); pose_data.orientation[3]);
deviceTDepth_ = imuTDevice_.inverse() * imuTDepthCamera_;
// camera intrinsic // camera intrinsic
TangoCameraIntrinsics color_camera_intrinsics; TangoCameraIntrinsics color_camera_intrinsics;
ret = TangoService_getCameraIntrinsics(TANGO_CAMERA_COLOR, &color_camera_intrinsics); ret = TangoService_getCameraIntrinsics(TANGO_CAMERA_COLOR, &color_camera_intrinsics);
@@ -311,11 +313,13 @@ bool CameraTango::init(const std::string & calibrationFolder, const std::string
this->getLocalTransform()); this->getLocalTransform());
model_.setImageSize(cv::Size(color_camera_intrinsics.width, color_camera_intrinsics.height)); model_.setImageSize(cv::Size(color_camera_intrinsics.width, color_camera_intrinsics.height));
// optical rotation // device to camera optical rotation in rtabmap frame
model_.setLocalTransform(Transform( model_.setLocalTransform(tango_device_T_rtabmap_device.inverse()*deviceTColorCamera_);
0.0f, 0.0f, 1.0f, 0.0f,
-1.0f, 0.0f, 0.0f, 0.0f, LOGI("deviceTColorCameraTango =%s", deviceTColorCamera_.prettyPrint().c_str());
0.0f, -1.0f, 0.0f, 0.0f)); LOGI("deviceTColorCameraRtabmap=%s", (tango_device_T_rtabmap_device.inverse()*deviceTColorCamera_).prettyPrint().c_str());
cameraStartedTime_.restart();
return true; return true;
} }
@@ -335,7 +339,7 @@ void CameraTango::cloudReceived(const cv::Mat & cloud, double timestamp)
{ {
if(this->isRunning()) if(this->isRunning())
{ {
UASSERT(cloud.type() == CV_32FC3); UASSERT(cloud.type() == CV_32FC4);
boost::mutex::scoped_lock lock(dataMutex_); boost::mutex::scoped_lock lock(dataMutex_);
bool notify = cloud_.empty(); bool notify = cloud_.empty();
@@ -375,11 +379,16 @@ void CameraTango::rgbReceived(const cv::Mat & tangoImage, int type, double times
} }
} }
static rtabmap::Transform opticalRotationTango(
1.0f, 0.0f, 0.0f, 0.0f,
0.0f, -1.0f, 0.0f, 0.0f,
0.0f, 0.0f, -1.0f, 0.0f);
void CameraTango::poseReceived(const Transform & pose) void CameraTango::poseReceived(const Transform & pose)
{ {
if(!pose.isNull() && pose.getNormSquared() < 100000) if(!pose.isNull() && pose.getNormSquared() < 100000)
{ {
this->post(new PoseEvent(pose)); // send pose of the camera (without optical rotation), not the device
this->post(new PoseEvent(pose*deviceTColorCamera_*opticalRotationTango));
} }
} }
@@ -398,73 +407,56 @@ std::string CameraTango::getSerial() const
return "Tango"; return "Tango";
} }
rtabmap::Transform CameraTango::tangoPoseToTransform(const TangoPoseData * tangoPose, bool inOpenGLFrame) const rtabmap::Transform CameraTango::tangoPoseToTransform(const TangoPoseData * tangoPose) const
{ {
UASSERT(tangoPose); UASSERT(tangoPose);
rtabmap::Transform pose; rtabmap::Transform pose;
if(!deviceTDepth_.isNull())
{
pose = rtabmap::Transform(
tangoPose->translation[0],
tangoPose->translation[1],
tangoPose->translation[2],
tangoPose->orientation[0],
tangoPose->orientation[1],
tangoPose->orientation[2],
tangoPose->orientation[3]);
// transform in OpenGL + extrinsics pose = rtabmap::Transform(
// opengl_world_T_opengl_camera = tangoPose->translation[0],
// opengl_world_T_start_service * tangoPose->translation[1],
// start_service_T_device * tangoPose->translation[2],
// device_T_imu * tangoPose->orientation[0],
// imu_T_depth_camera * tangoPose->orientation[1],
// depth_camera_T_opengl_camera; tangoPose->orientation[2],
if(inOpenGLFrame) tangoPose->orientation[3]);
{
pose = opengl_world_T_tango_world * pose * deviceTDepth_ * depth_camera_T_opengl_camera;
}
}
return pose; return pose;
} }
rtabmap::Transform CameraTango::getPoseAtTimestamp(double timestamp, bool inOpenGLFrame) rtabmap::Transform CameraTango::getPoseAtTimestamp(double timestamp)
{ {
rtabmap::Transform pose; rtabmap::Transform pose;
if(!deviceTDepth_.isNull())
TangoPoseData pose_start_service_T_device;
TangoCoordinateFramePair frame_pair;
frame_pair.base = TANGO_COORDINATE_FRAME_START_OF_SERVICE;
frame_pair.target = TANGO_COORDINATE_FRAME_DEVICE;
TangoErrorType status = TangoService_getPoseAtTime(timestamp, frame_pair, &pose_start_service_T_device);
if (status != TANGO_SUCCESS)
{ {
TangoPoseData pose_start_service_T_device; LOGE(
TangoCoordinateFramePair frame_pair; "PoseData: Failed to get transform between the Start of service and "
frame_pair.base = TANGO_COORDINATE_FRAME_START_OF_SERVICE; "device frames at timestamp %lf",
frame_pair.target = TANGO_COORDINATE_FRAME_DEVICE; timestamp);
TangoErrorType status = TangoService_getPoseAtTime(timestamp, frame_pair, &pose_start_service_T_device);
if (status != TANGO_SUCCESS)
{
LOGE(
"PoseData: Failed to get transform between the Start of service and "
"device frames at timestamp %lf",
timestamp);
}
if (pose_start_service_T_device.status_code != TANGO_POSE_VALID)
{
LOGW(
"PoseData: Failed to get transform between the Start of service and "
"device frames at timestamp %lf",
timestamp);
}
else
{
pose = tangoPoseToTransform(&pose_start_service_T_device, inOpenGLFrame);
}
} }
if (pose_start_service_T_device.status_code != TANGO_POSE_VALID)
{
LOGW(
"PoseData: Failed to get transform between the Start of service and "
"device frames at timestamp %lf",
timestamp);
}
else
{
pose = tangoPoseToTransform(&pose_start_service_T_device);
}
return pose; return pose;
} }
SensorData CameraTango::captureImage() SensorData CameraTango::captureImage(CameraInfo * info)
{ {
LOGI("Capturing image..."); LOGI("Capturing image...");
@@ -544,35 +536,54 @@ SensorData CameraTango::captureImage()
// Querying the depth image's frame transformation based on the depth image's // Querying the depth image's frame transformation based on the depth image's
// timestamp. // timestamp.
cv::Mat depth; cv::Mat depth;
Transform poseDepth = getPoseAtTimestamp(cloudStamp, false);
Transform poseColor = getPoseAtTimestamp(rgbStamp, false);
if(poseColor.getNormSquared() > 100000) // Calculate the relative pose from color camera frame at timestamp
// color_timestamp t1 and depth
// camera frame at depth_timestamp t0.
Transform colorToDepth;
TangoPoseData pose_color_image_t1_T_depth_image_t0;
if (TangoSupport_calculateRelativePose(
rgbStamp, TANGO_COORDINATE_FRAME_CAMERA_COLOR, cloudStamp,
TANGO_COORDINATE_FRAME_CAMERA_DEPTH,
&pose_color_image_t1_T_depth_image_t0) == TANGO_SUCCESS)
{ {
LOGE("Very large odometry color pose detected (%s)! Ignoring this frame!", poseColor.prettyPrint().c_str()); colorToDepth = tangoPoseToTransform(&pose_color_image_t1_T_depth_image_t0);
poseColor.setNull();
} }
if(poseDepth.getNormSquared() > 100000) else
{ {
LOGE("Very large odometry depth pose detected (%s)! Ignoring this frame!", poseDepth.prettyPrint().c_str()); LOGE(
poseDepth.setNull(); "SynchronizationApplication: Could not find a valid relative pose at "
"time for color and "
" depth cameras.");
} }
if(!poseDepth.isNull() && !poseColor.isNull()) if(colorToDepth.getNormSquared() > 100000)
{
LOGE("Very large color to depth error detected (%s)! Ignoring this frame!", colorToDepth.prettyPrint().c_str());
colorToDepth.setNull();
}
cv::Mat scan;
if(!colorToDepth.isNull())
{ {
// The Color Camera frame at timestamp t0 with respect to Depth // The Color Camera frame at timestamp t0 with respect to Depth
// Camera frame at timestamp t1. // Camera frame at timestamp t1.
Transform colorToDepth = deviceTDepth_.inverse() * poseColor.inverse() * poseDepth * deviceTDepth_;
LOGI("colorToDepth=%s", colorToDepth.prettyPrint().c_str()); LOGI("colorToDepth=%s", colorToDepth.prettyPrint().c_str());
int pixelsSet = 0; int pixelsSet = 0;
depth = cv::Mat::zeros(model_.imageHeight()/8, model_.imageWidth()/8, CV_16UC1); // mm depth = cv::Mat::zeros(model_.imageHeight()/8, model_.imageWidth()/8, CV_16UC1); // mm
CameraModel depthModel = model_.scaled(1.0f/8.0f); CameraModel depthModel = model_.scaled(1.0f/8.0f);
std::vector<cv::Point3f> scanData(cloud.total());
int oi=0;
for(unsigned int i=0; i<cloud.total(); ++i) for(unsigned int i=0; i<cloud.total(); ++i)
{ {
cv::Vec3f & p = cloud.at<cv::Vec3f>(i); float * p = cloud.ptr<float>(0,i);
cv::Point3f pt = util3d::transformPoint(cv::Point3f(p[0], p[1], p[2]), colorToDepth); cv::Point3f pt = util3d::transformPoint(cv::Point3f(p[0], p[1], p[2]), colorToDepth);
if(pt.z > 0.0f && i%scanDownsampling == 0)
{
scanData.at(oi++) = pt;
}
int pixel_x, pixel_y; int pixel_x, pixel_y;
// get the coordinate on image plane. // get the coordinate on image plane.
pixel_x = static_cast<int>((depthModel.fx()) * (pt.x / pt.z) + depthModel.cx()); pixel_x = static_cast<int>((depthModel.fx()) * (pt.x / pt.z) + depthModel.cx());
@@ -591,23 +602,35 @@ SensorData CameraTango::captureImage()
} }
} }
} }
if(oi)
{
scan = cv::Mat(1, oi, CV_32FC3, scanData.data()).clone();
}
LOGI("pixels depth set= %d", pixelsSet); LOGI("pixels depth set= %d", pixelsSet);
} }
else else
{ {
LOGE("Poses are null?!? color=%d (stamp=%f) depth=%d (stamp=%f)", poseColor.isNull()?0:1, rgbStamp, poseDepth.isNull()?0:1, cloudStamp); LOGE("color to depth pose is null?!? (rgb stamp=%f) (depth stamp=%f)", rgbStamp, cloudStamp);
} }
if(!rgb.empty() && !depth.empty()) if(!rgb.empty() && !depth.empty())
{ {
depth = rtabmap::util2d::fillDepthHoles(depth, holeSize, maxDepthError); depth = rtabmap::util2d::fillDepthHoles(depth, holeSize, maxDepthError);
Transform poseColorOpenGL = getPoseAtTimestamp(rgbStamp, true); Transform poseDevice = getPoseAtTimestamp(rgbStamp);
LOGD("Local = %s", model.localTransform().prettyPrint().c_str());
LOGD("tango = %s", poseDevice.prettyPrint().c_str());
LOGD("opengl(t)= %s", (opengl_world_T_tango_world * poseDevice).prettyPrint().c_str());
//Rotate in RTAB-Map's coordinate //Rotate in RTAB-Map's coordinate
Transform odom = rtabmap_world_T_opengl_world * poseColorOpenGL * depth_camera_T_opengl_camera * model.localTransform().inverse(); Transform odom = rtabmap_world_T_tango_world * poseDevice * tango_device_T_rtabmap_device;
data = SensorData(rgb, depth, model, this->getNextSeqID(), rgbStamp); LOGD("rtabmap = %s", odom.prettyPrint().c_str());
LOGD("opengl(r)= %s", (opengl_world_T_rtabmap_world * odom * rtabmap_device_T_opengl_device).prettyPrint().c_str());
data = SensorData(scan, LaserScanInfo(cloud.total()/scanDownsampling, 0, model.localTransform()), rgb, depth, model, this->getNextSeqID(), rgbStamp);
data.setGroundTruth(odom); data.setGroundTruth(odom);
} }
else else
@@ -621,7 +644,11 @@ SensorData CameraTango::captureImage()
void CameraTango::mainLoopBegin() void CameraTango::mainLoopBegin()
{ {
uSleep(2000); // just to make sure that the camera is started double t = cameraStartedTime_.elapsed();
if(t < 5.0)
{
uSleep((5.0-t)*1000); // just to make sure that the camera is started
}
} }
void CameraTango::mainLoop() void CameraTango::mainLoop()

View File

@@ -34,6 +34,7 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include <rtabmap/utilite/UEventsSender.h> #include <rtabmap/utilite/UEventsSender.h>
#include <rtabmap/utilite/UThread.h> #include <rtabmap/utilite/UThread.h>
#include <rtabmap/utilite/UEvent.h> #include <rtabmap/utilite/UEvent.h>
#include <rtabmap/utilite/UTimer.h>
#include <boost/thread/mutex.hpp> #include <boost/thread/mutex.hpp>
class TangoPoseData; class TangoPoseData;
@@ -76,7 +77,8 @@ public:
void close(); // close Tango connection void close(); // close Tango connection
virtual bool isCalibrated() const; virtual bool isCalibrated() const;
virtual std::string getSerial() const; virtual std::string getSerial() const;
rtabmap::Transform tangoPoseToTransform(const TangoPoseData * tangoPose, bool inOpenGLFrame) const; const CameraModel & getCameraModel() const {return model_;}
rtabmap::Transform tangoPoseToTransform(const TangoPoseData * tangoPose) const;
void setDecimation(int value) {decimation_ = value;} void setDecimation(int value) {decimation_ = value;}
void setAutoExposure(bool enabled) {autoExposure_ = enabled;} void setAutoExposure(bool enabled) {autoExposure_ = enabled;}
@@ -86,10 +88,10 @@ public:
void tangoEventReceived(int type, const char * key, const char * value); void tangoEventReceived(int type, const char * key, const char * value);
protected: protected:
virtual SensorData captureImage(); virtual SensorData captureImage(CameraInfo * info = 0);
private: private:
rtabmap::Transform getPoseAtTimestamp(double timestamp, bool inOpenGLFrame); rtabmap::Transform getPoseAtTimestamp(double timestamp);
virtual void mainLoopBegin(); virtual void mainLoopBegin();
virtual void mainLoop(); virtual void mainLoop();
@@ -97,6 +99,7 @@ private:
private: private:
void * tango_config_; void * tango_config_;
bool firstFrame_; bool firstFrame_;
UTimer cameraStartedTime_;
int decimation_; int decimation_;
bool autoExposure_; bool autoExposure_;
cv::Mat cloud_; cv::Mat cloud_;
@@ -106,10 +109,8 @@ private:
double tangoColorStamp_; double tangoColorStamp_;
boost::mutex dataMutex_; boost::mutex dataMutex_;
USemaphore dataReady_; USemaphore dataReady_;
rtabmap::Transform imuTDevice_;
rtabmap::Transform imuTDepthCamera_;
rtabmap::Transform deviceTDepth_;
CameraModel model_; CameraModel model_;
Transform deviceTColorCamera_;
}; };
} /* namespace rtabmap */ } /* namespace rtabmap */

File diff suppressed because it is too large Load Diff

View File

@@ -52,7 +52,7 @@ class RTABMapApp : public UEventsHandler {
void onCreate(JNIEnv* env, jobject caller_activity); void onCreate(JNIEnv* env, jobject caller_activity);
void openDatabase(const std::string & databasePath); void openDatabase(const std::string & databasePath = "");
bool onTangoServiceConnected(JNIEnv* env, jobject iBinder); bool onTangoServiceConnected(JNIEnv* env, jobject iBinder);
@@ -112,21 +112,26 @@ class RTABMapApp : public UEventsHandler {
void setPausedMapping(bool paused); void setPausedMapping(bool paused);
void setMapCloudShown(bool shown); void setMapCloudShown(bool shown);
void setOdomCloudShown(bool shown); void setOdomCloudShown(bool shown);
void setMeshRendering(bool enabled); void setMeshRendering(bool enabled, bool withTexture);
void setLocalizationMode(bool enabled); void setLocalizationMode(bool enabled);
void setTrajectoryMode(bool enabled); void setTrajectoryMode(bool enabled);
void setGraphOptimization(bool enabled); void setGraphOptimization(bool enabled);
void setNodesFiltering(bool enabled); void setNodesFiltering(bool enabled);
void setDriftCorrection(bool enabled);
void setGraphVisible(bool visible); void setGraphVisible(bool visible);
void setGridVisible(bool visible);
void setAutoExposure(bool enabled); void setAutoExposure(bool enabled);
void setFullResolution(bool enabled); void setFullResolution(bool enabled);
void setAppendMode(bool enabled);
void setDataRecorderMode(bool enabled);
void setMaxCloudDepth(float value); void setMaxCloudDepth(float value);
void setMeshDecimation(int value);
void setMeshAngleTolerance(float value); void setMeshAngleTolerance(float value);
void setMeshTriangleSize(int value); void setMeshTriangleSize(int value);
int setMappingParameter(const std::string & key, const std::string & value); int setMappingParameter(const std::string & key, const std::string & value);
void resetMapping(); void resetMapping();
void save(); void save(const std::string & databasePath);
bool exportMesh(const std::string & filePath); bool exportMesh(const std::string & filePath);
int postProcessing(int approach); int postProcessing(int approach);
@@ -135,6 +140,7 @@ class RTABMapApp : public UEventsHandler {
private: private:
rtabmap::ParametersMap getRtabmapParameters(); rtabmap::ParametersMap getRtabmapParameters();
bool smoothMesh(int id, Mesh & mesh);
private: private:
rtabmap::CameraTango * camera_; rtabmap::CameraTango * camera_;
@@ -145,22 +151,30 @@ class RTABMapApp : public UEventsHandler {
bool odomCloudShown_; bool odomCloudShown_;
bool graphOptimization_; bool graphOptimization_;
bool nodesFiltering_; bool nodesFiltering_;
bool driftCorrection_;
bool localizationMode_; bool localizationMode_;
bool trajectoryMode_; bool trajectoryMode_;
bool autoExposure_; bool autoExposure_;
bool fullResolution_; bool fullResolution_;
bool appendMode_;
float maxCloudDepth_; float maxCloudDepth_;
int meshDecimation_;
int meshTrianglePix_; int meshTrianglePix_;
float meshAngleToleranceDeg_; float meshAngleToleranceDeg_;
rtabmap::ParametersMap mappingParameters_; rtabmap::ParametersMap mappingParameters_;
bool paused_;
bool dataRecorderMode_;
bool clearSceneOnNextRender_; bool clearSceneOnNextRender_;
bool filterPolygonsOnNextRender_;
int gainCompensationOnNextRender_;
bool bilateralFilteringOnNextRender_;
bool cameraJustInitialized_;
int totalPoints_; int totalPoints_;
int totalPolygons_; int totalPolygons_;
int lastDrawnCloudsCount_; int lastDrawnCloudsCount_;
float renderingFPS_; float renderingTime_;
// main_scene_ includes all drawable object for visualizing Tango device's // main_scene_ includes all drawable object for visualizing Tango device's
// movement and point cloud. // movement and point cloud.
@@ -174,14 +188,7 @@ class RTABMapApp : public UEventsHandler {
boost::mutex meshesMutex_; boost::mutex meshesMutex_;
boost::mutex odomMutex_; boost::mutex odomMutex_;
boost::mutex poseMutex_; boost::mutex poseMutex_;
boost::mutex renderingMutex_;
struct Mesh
{
pcl::PointCloud<pcl::PointXYZRGB>::Ptr cloud;
std::vector<pcl::Vertices> polygons;
rtabmap::Transform pose;
cv::Mat texture;
};
std::map<int, Mesh> createdMeshes_; std::map<int, Mesh> createdMeshes_;
std::map<int, rtabmap::Transform> rawPoses_; std::map<int, rtabmap::Transform> rawPoses_;

View File

@@ -55,6 +55,13 @@ Java_com_introlab_rtabmap_RTABMapLib_onCreate(
return app.onCreate(env, activity); return app.onCreate(env, activity);
} }
JNIEXPORT void JNICALL
Java_com_introlab_rtabmap_RTABMapLib_openEmptyDatabase(
JNIEnv* env, jobject)
{
return app.openDatabase();
}
JNIEXPORT void JNICALL JNIEXPORT void JNICALL
Java_com_introlab_rtabmap_RTABMapLib_openDatabase( Java_com_introlab_rtabmap_RTABMapLib_openDatabase(
JNIEnv* env, jobject, jstring databasePath) JNIEnv* env, jobject, jstring databasePath)
@@ -133,9 +140,9 @@ Java_com_introlab_rtabmap_RTABMapLib_setOdomCloudShown(
} }
JNIEXPORT void JNICALL JNIEXPORT void JNICALL
Java_com_introlab_rtabmap_RTABMapLib_setMeshRendering( Java_com_introlab_rtabmap_RTABMapLib_setMeshRendering(
JNIEnv*, jobject, bool enabled) JNIEnv*, jobject, bool enabled, bool withTexture)
{ {
return app.setMeshRendering(enabled); return app.setMeshRendering(enabled, withTexture);
} }
JNIEXPORT void JNICALL JNIEXPORT void JNICALL
Java_com_introlab_rtabmap_RTABMapLib_setLocalizationMode( Java_com_introlab_rtabmap_RTABMapLib_setLocalizationMode(
@@ -162,12 +169,24 @@ Java_com_introlab_rtabmap_RTABMapLib_setNodesFiltering(
return app.setNodesFiltering(enabled); return app.setNodesFiltering(enabled);
} }
JNIEXPORT void JNICALL JNIEXPORT void JNICALL
Java_com_introlab_rtabmap_RTABMapLib_setDriftCorrection(
JNIEnv*, jobject, bool enabled)
{
return app.setDriftCorrection(enabled);
}
JNIEXPORT void JNICALL
Java_com_introlab_rtabmap_RTABMapLib_setGraphVisible( Java_com_introlab_rtabmap_RTABMapLib_setGraphVisible(
JNIEnv*, jobject, bool visible) JNIEnv*, jobject, bool visible)
{ {
return app.setGraphVisible(visible); return app.setGraphVisible(visible);
} }
JNIEXPORT void JNICALL JNIEXPORT void JNICALL
Java_com_introlab_rtabmap_RTABMapLib_setGridVisible(
JNIEnv*, jobject, bool visible)
{
return app.setGridVisible(visible);
}
JNIEXPORT void JNICALL
Java_com_introlab_rtabmap_RTABMapLib_setAutoExposure( Java_com_introlab_rtabmap_RTABMapLib_setAutoExposure(
JNIEnv*, jobject, bool enabled) JNIEnv*, jobject, bool enabled)
{ {
@@ -180,12 +199,30 @@ Java_com_introlab_rtabmap_RTABMapLib_setFullResolution(
return app.setFullResolution(enabled); return app.setFullResolution(enabled);
} }
JNIEXPORT void JNICALL JNIEXPORT void JNICALL
Java_com_introlab_rtabmap_RTABMapLib_setAppendMode(
JNIEnv*, jobject, bool enabled)
{
return app.setAppendMode(enabled);
}
JNIEXPORT void JNICALL
Java_com_introlab_rtabmap_RTABMapLib_setDataRecorderMode(
JNIEnv*, jobject, bool enabled)
{
return app.setDataRecorderMode(enabled);
}
JNIEXPORT void JNICALL
Java_com_introlab_rtabmap_RTABMapLib_setMaxCloudDepth( Java_com_introlab_rtabmap_RTABMapLib_setMaxCloudDepth(
JNIEnv*, jobject, float value) JNIEnv*, jobject, float value)
{ {
return app.setMaxCloudDepth(value); return app.setMaxCloudDepth(value);
} }
JNIEXPORT void JNICALL JNIEXPORT void JNICALL
Java_com_introlab_rtabmap_RTABMapLib_setMeshDecimation(
JNIEnv*, jobject, int value)
{
return app.setMeshDecimation(value);
}
JNIEXPORT void JNICALL
Java_com_introlab_rtabmap_RTABMapLib_setMeshAngleTolerance( Java_com_introlab_rtabmap_RTABMapLib_setMeshAngleTolerance(
JNIEnv*, jobject, float value) JNIEnv*, jobject, float value)
{ {
@@ -216,9 +253,11 @@ Java_com_introlab_rtabmap_RTABMapLib_resetMapping(
JNIEXPORT void JNICALL JNIEXPORT void JNICALL
Java_com_introlab_rtabmap_RTABMapLib_save( Java_com_introlab_rtabmap_RTABMapLib_save(
JNIEnv* env, jobject) JNIEnv* env, jobject, jstring databasePath)
{ {
return app.save(); std::string databasePathC;
GetJStringContent(env,databasePath,databasePathC);
return app.save(databasePathC);
} }
JNIEXPORT bool JNICALL JNIEXPORT bool JNICALL

View File

@@ -39,120 +39,35 @@ PointCloudDrawable::PointCloudDrawable(
GLuint cloudShaderProgram, GLuint cloudShaderProgram,
GLuint textureShaderProgram, GLuint textureShaderProgram,
const pcl::PointCloud<pcl::PointXYZRGB>::Ptr & cloud, const pcl::PointCloud<pcl::PointXYZRGB>::Ptr & cloud,
const std::vector<pcl::Vertices> & polygons, const pcl::IndicesPtr & indices,
const cv::Mat & image) : float gain) :
vertex_buffers_(0), vertex_buffers_(0),
textures_(0), textures_(0),
nPoints_(0), nPoints_(0),
pose_(1.0f), pose_(1.0f),
visible_(true), visible_(true),
cloud_shader_program_(cloudShaderProgram), cloud_shader_program_(cloudShaderProgram),
texture_shader_program_(textureShaderProgram) texture_shader_program_(textureShaderProgram),
gain_(1.0f)
{ {
UASSERT(!cloud->empty()); updateCloud(cloud, indices, gain);
}
glGenBuffers(1, &vertex_buffers_); PointCloudDrawable::PointCloudDrawable(
if(!vertex_buffers_) GLuint cloudShaderProgram,
{ GLuint textureShaderProgram,
LOGE("OpenGL: could not generate vertex buffers\n"); const Mesh & mesh,
return; const cv::Mat & texture) :
} vertex_buffers_(0),
textures_(0),
if(!cloud->is_dense && !image.empty()) nPoints_(0),
{ pose_(1.0f),
LOGI("cloud=%dx%d image=%dx%d\n", (int)cloud->width, (int)cloud->height, image.cols, image.rows); visible_(true),
UASSERT(polygons.size() && !cloud->is_dense && !image.empty() && image.type() == CV_8UC3); cloud_shader_program_(cloudShaderProgram),
glGenTextures(1, &textures_); texture_shader_program_(textureShaderProgram),
if(!textures_) gain_(1.0f)
{ {
vertex_buffers_ = 0; updateMesh(mesh, texture);
LOGE("OpenGL: could not generate vertex buffers\n");
return;
}
}
LOGI("Creating cloud buffer %d", vertex_buffers_);
std::vector<float> vertices;
if(textures_)
{
vertices = std::vector<float>(cloud->size()*6);
for(unsigned int i=0; i<cloud->size(); ++i)
{
vertices[i*6] = cloud->at(i).x;
vertices[i*6+1] = cloud->at(i).y;
vertices[i*6+2] = cloud->at(i).z;
// rgb
vertices[i*6+3] = cloud->at(i).rgb;
// texture uv
vertices[i*6+4] = float(i % cloud->width)/float(cloud->width); //u
vertices[i*6+5] = float(i/cloud->width)/float(cloud->height); //v
}
}
else
{
vertices = std::vector<float>(cloud->size()*4);
for(unsigned int i=0; i<cloud->size(); ++i)
{
vertices[i*4] = cloud->at(i).x;
vertices[i*4+1] = cloud->at(i).y;
vertices[i*4+2] = cloud->at(i).z;
vertices[i*4+3] = cloud->at(i).rgb;
}
}
glBindBuffer(GL_ARRAY_BUFFER, vertex_buffers_);
glBufferData(GL_ARRAY_BUFFER, sizeof(GLfloat) * (int)vertices.size(), (const void *)vertices.data(), GL_STATIC_DRAW);
glBindBuffer(GL_ARRAY_BUFFER, 0);
GLint error = glGetError();
if(error != GL_NO_ERROR)
{
LOGE("OpenGL: Could not allocate point cloud (0x%x)\n", error);
vertex_buffers_ = 0;
return;
}
if(textures_)
{
// gen texture from image
glBindTexture(GL_TEXTURE_2D, textures_);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
cv::Mat rgbImage;
cv::cvtColor(image, rgbImage, CV_BGR2RGB);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, rgbImage.cols, rgbImage.rows, 0, GL_RGB, GL_UNSIGNED_BYTE, rgbImage.data);
GLint error = glGetError();
if(error != GL_NO_ERROR)
{
LOGE("OpenGL: Could not allocate texture (0x%x)\n", error);
textures_ = 0;
glDeleteBuffers(1, &vertex_buffers_);
vertex_buffers_ = 0;
return;
}
}
nPoints_ = cloud->size();
if(polygons.size())
{
int polygonSize = polygons[0].vertices.size();
UASSERT(polygonSize == 3);
polygons_.resize(polygons.size() * polygonSize);
int oi = 0;
for(unsigned int i=0; i<polygons.size(); ++i)
{
UASSERT((int)polygons[i].vertices.size() == polygonSize);
for(int j=0; j<polygonSize; ++j)
{
polygons_[oi++] = (unsigned short)polygons[i].vertices[j];
}
}
}
} }
PointCloudDrawable::~PointCloudDrawable() PointCloudDrawable::~PointCloudDrawable()
@@ -173,6 +88,202 @@ PointCloudDrawable::~PointCloudDrawable()
} }
} }
void PointCloudDrawable::updatePolygons(const std::vector<pcl::Vertices> & polygons)
{
polygons_.clear();
if(polygons.size() && organizedToDenseIndices_.size())
{
int polygonSize = polygons[0].vertices.size();
UASSERT(polygonSize == 3);
polygons_.resize(polygons.size() * polygonSize);
int oi = 0;
for(unsigned int i=0; i<polygons.size(); ++i)
{
UASSERT((int)polygons[i].vertices.size() == polygonSize);
for(int j=0; j<polygonSize; ++j)
{
polygons_[oi++] = organizedToDenseIndices_.at((unsigned short)polygons[i].vertices[j]);
}
}
}
}
void PointCloudDrawable::updateCloud(const pcl::PointCloud<pcl::PointXYZRGB>::Ptr & cloud, const pcl::IndicesPtr & indices, float gain)
{
UASSERT(cloud.get() && !cloud->empty() && indices.get() && !indices->empty());
nPoints_ = 0;
polygons_.clear();
gain_ = gain;
if (vertex_buffers_)
{
glDeleteBuffers(1, &vertex_buffers_);
tango_gl::util::CheckGlError("PointCloudDrawable::~PointCloudDrawable()");
vertex_buffers_ = 0;
}
if (textures_)
{
glDeleteTextures(1, &textures_);
tango_gl::util::CheckGlError("PointCloudDrawable::~PointCloudDrawable()");
textures_ = 0;
}
glGenBuffers(1, &vertex_buffers_);
if(!vertex_buffers_)
{
LOGE("OpenGL: could not generate vertex buffers\n");
return;
}
LOGI("Creating cloud buffer %d", vertex_buffers_);
std::vector<float> vertices(indices->size()*4);
for(unsigned int i=0; i<indices->size(); ++i)
{
vertices[i*4] = cloud->at(indices->at(i)).x;
vertices[i*4+1] = cloud->at(indices->at(i)).y;
vertices[i*4+2] = cloud->at(indices->at(i)).z;
vertices[i*4+3] = cloud->at(indices->at(i)).rgb;
}
glBindBuffer(GL_ARRAY_BUFFER, vertex_buffers_);
glBufferData(GL_ARRAY_BUFFER, sizeof(GLfloat) * (int)vertices.size(), (const void *)vertices.data(), GL_STATIC_DRAW);
glBindBuffer(GL_ARRAY_BUFFER, 0);
GLint error = glGetError();
if(error != GL_NO_ERROR)
{
LOGE("OpenGL: Could not allocate point cloud (0x%x)\n", error);
vertex_buffers_ = 0;
return;
}
nPoints_ = indices->size();
}
void PointCloudDrawable::updateMesh(const Mesh & mesh, const cv::Mat & texture)
{
UASSERT(mesh.cloud.get() && !mesh.cloud->empty() && mesh.indices.get() && !mesh.indices->empty());
nPoints_ = 0;
if (vertex_buffers_)
{
glDeleteBuffers(1, &vertex_buffers_);
tango_gl::util::CheckGlError("PointCloudDrawable::~PointCloudDrawable()");
vertex_buffers_ = 0;
}
gain_ = mesh.gain;
bool textureUpdate = false;
if(!texture.empty() && texture.type() == CV_8UC3)
{
if (textures_)
{
glDeleteTextures(1, &textures_);
tango_gl::util::CheckGlError("PointCloudDrawable::~PointCloudDrawable()");
textures_ = 0;
}
textureUpdate = true;
}
glGenBuffers(1, &vertex_buffers_);
if(!vertex_buffers_)
{
LOGE("OpenGL: could not generate vertex buffers\n");
return;
}
if(textureUpdate)
{
UASSERT(!mesh.cloud->is_dense);
glGenTextures(1, &textures_);
if(!textures_)
{
vertex_buffers_ = 0;
LOGE("OpenGL: could not generate texture buffers\n");
return;
}
}
LOGI("Creating cloud buffer %d", vertex_buffers_);
std::vector<float> vertices;
organizedToDenseIndices_ = std::vector<int>(mesh.cloud->width*mesh.cloud->height, -1);
if(textures_)
{
vertices = std::vector<float>(mesh.indices->size()*6);
for(unsigned int i=0; i<mesh.indices->size(); ++i)
{
vertices[i*6] = mesh.cloud->at(mesh.indices->at(i)).x;
vertices[i*6+1] = mesh.cloud->at(mesh.indices->at(i)).y;
vertices[i*6+2] = mesh.cloud->at(mesh.indices->at(i)).z;
// rgb
vertices[i*6+3] = mesh.cloud->at(mesh.indices->at(i)).rgb;
// texture uv
int index = mesh.indices->at(i);
vertices[i*6+4] = float(index % mesh.cloud->width)/float(mesh.cloud->width); //u
vertices[i*6+5] = float(index / mesh.cloud->width)/float(mesh.cloud->height); //v
organizedToDenseIndices_[mesh.indices->at(i)] = i;
}
}
else
{
vertices = std::vector<float>(mesh.indices->size()*4);
for(unsigned int i=0; i<mesh.indices->size(); ++i)
{
vertices[i*4] = mesh.cloud->at(mesh.indices->at(i)).x;
vertices[i*4+1] = mesh.cloud->at(mesh.indices->at(i)).y;
vertices[i*4+2] = mesh.cloud->at(mesh.indices->at(i)).z;
vertices[i*4+3] = mesh.cloud->at(mesh.indices->at(i)).rgb;
organizedToDenseIndices_[mesh.indices->at(i)] = i;
}
}
glBindBuffer(GL_ARRAY_BUFFER, vertex_buffers_);
glBufferData(GL_ARRAY_BUFFER, sizeof(GLfloat) * (int)vertices.size(), (const void *)vertices.data(), GL_STATIC_DRAW);
glBindBuffer(GL_ARRAY_BUFFER, 0);
GLint error = glGetError();
if(error != GL_NO_ERROR)
{
LOGE("OpenGL: Could not allocate point cloud (0x%x)\n", error);
vertex_buffers_ = 0;
return;
}
if(textures_ && textureUpdate)
{
// gen texture from image
glBindTexture(GL_TEXTURE_2D, textures_);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
cv::Mat rgbImage;
cv::cvtColor(texture, rgbImage, CV_BGR2RGB);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, rgbImage.cols, rgbImage.rows, 0, GL_RGB, GL_UNSIGNED_BYTE, rgbImage.data);
GLint error = glGetError();
if(error != GL_NO_ERROR)
{
LOGE("OpenGL: Could not allocate texture (0x%x)\n", error);
textures_ = 0;
glDeleteBuffers(1, &vertex_buffers_);
vertex_buffers_ = 0;
return;
}
}
nPoints_ = mesh.indices->size();
if(polygons_.size() != mesh.polygons.size())
{
updatePolygons(mesh.polygons);
}
}
void PointCloudDrawable::setPose(const rtabmap::Transform & pose) void PointCloudDrawable::setPose(const rtabmap::Transform & pose)
{ {
UASSERT(!pose.isNull()); UASSERT(!pose.isNull());
@@ -180,11 +291,11 @@ void PointCloudDrawable::setPose(const rtabmap::Transform & pose)
pose_ = glmFromTransform(pose); pose_ = glmFromTransform(pose);
} }
void PointCloudDrawable::Render(const glm::mat4 & projectionMatrix, const glm::mat4 & viewMatrix, bool meshRendering, float pointSize) { void PointCloudDrawable::Render(const glm::mat4 & projectionMatrix, const glm::mat4 & viewMatrix, bool meshRendering, float pointSize, bool textureRendering) {
if(vertex_buffers_ && nPoints_ && visible_) if(vertex_buffers_ && nPoints_ && visible_)
{ {
if(meshRendering && textures_) if(meshRendering && textureRendering && textures_)
{ {
glUseProgram(texture_shader_program_); glUseProgram(texture_shader_program_);
@@ -200,6 +311,9 @@ void PointCloudDrawable::Render(const glm::mat4 & projectionMatrix, const glm::m
GLuint texture_handle = glGetUniformLocation(texture_shader_program_, "u_Texture"); GLuint texture_handle = glGetUniformLocation(texture_shader_program_, "u_Texture");
glUniform1i(texture_handle, 0); glUniform1i(texture_handle, 0);
GLuint gain_handle = glGetUniformLocation(texture_shader_program_, "u_gain");
glUniform1f(gain_handle, gain_);
GLint attribute_vertex = glGetAttribLocation(texture_shader_program_, "vertex"); GLint attribute_vertex = glGetAttribLocation(texture_shader_program_, "vertex");
GLint attribute_texture = glGetAttribLocation(texture_shader_program_, "a_TexCoordinate"); GLint attribute_texture = glGetAttribLocation(texture_shader_program_, "a_TexCoordinate");
@@ -222,6 +336,9 @@ void PointCloudDrawable::Render(const glm::mat4 & projectionMatrix, const glm::m
GLuint point_size_handle_ = glGetUniformLocation(cloud_shader_program_, "point_size"); GLuint point_size_handle_ = glGetUniformLocation(cloud_shader_program_, "point_size");
glUniform1f(point_size_handle_, pointSize); glUniform1f(point_size_handle_, pointSize);
GLuint gain_handle = glGetUniformLocation(cloud_shader_program_, "u_gain");
glUniform1f(gain_handle, gain_);
GLint attribute_vertex = glGetAttribLocation(cloud_shader_program_, "vertex"); GLint attribute_vertex = glGetAttribLocation(cloud_shader_program_, "vertex");
GLint attribute_color = glGetAttribLocation(cloud_shader_program_, "color"); GLint attribute_color = glGetAttribLocation(cloud_shader_program_, "color");

View File

@@ -45,14 +45,23 @@ class PointCloudDrawable {
GLuint cloudShaderProgram, GLuint cloudShaderProgram,
GLuint textureShaderProgram, GLuint textureShaderProgram,
const pcl::PointCloud<pcl::PointXYZRGB>::Ptr & cloud, const pcl::PointCloud<pcl::PointXYZRGB>::Ptr & cloud,
const std::vector<pcl::Vertices> & polygons = std::vector<pcl::Vertices>(), const pcl::IndicesPtr & indices,
const cv::Mat & image = cv::Mat()); float gain);
PointCloudDrawable(
GLuint cloudShaderProgram,
GLuint textureShaderProgram,
const Mesh & mesh,
const cv::Mat & texture);
virtual ~PointCloudDrawable(); virtual ~PointCloudDrawable();
void updatePolygons(const std::vector<pcl::Vertices> & polygons);
void updateCloud(const pcl::PointCloud<pcl::PointXYZRGB>::Ptr & cloud, const pcl::IndicesPtr & indices, float gain);
void updateMesh(const Mesh & mesh, const cv::Mat & texture);
void setPose(const rtabmap::Transform & pose); void setPose(const rtabmap::Transform & pose);
void setVisible(bool visible) {visible_=visible;} void setVisible(bool visible) {visible_=visible;}
rtabmap::Transform getPose() const {return glmToTransform(pose_);} rtabmap::Transform getPose() const {return glmToTransform(pose_);}
bool isVisible() const {return visible_;} bool isVisible() const {return visible_;}
bool hasTexture() const {return textures_ != 0;}
// Update current point cloud data. // Update current point cloud data.
// //
@@ -60,7 +69,7 @@ class PointCloudDrawable {
// @param view_mat: view matrix from current render camera. // @param view_mat: view matrix from current render camera.
// @param model_mat: model matrix for this point cloud frame. // @param model_mat: model matrix for this point cloud frame.
// @param vertices: all vertices in this point cloud frame. // @param vertices: all vertices in this point cloud frame.
void Render(const glm::mat4 & projectionMatrix, const glm::mat4 & viewMatrix, bool meshRendering = true, float pointSize = 3.0f); void Render(const glm::mat4 & projectionMatrix, const glm::mat4 & viewMatrix, bool meshRendering = true, float pointSize = 3.0f, bool textureRendering = false);
private: private:
// Vertex buffer of the point cloud geometry. // Vertex buffer of the point cloud geometry.
@@ -70,9 +79,12 @@ class PointCloudDrawable {
int nPoints_; int nPoints_;
glm::mat4 pose_; glm::mat4 pose_;
bool visible_; bool visible_;
std::vector<int> organizedToDenseIndices_;
GLuint cloud_shader_program_; GLuint cloud_shader_program_;
GLuint texture_shader_program_; GLuint texture_shader_program_;
float gain_;
}; };
#endif // TANGO_POINT_CLOUD_POINT_CLOUD_DRAWABLE_H_ #endif // TANGO_POINT_CLOUD_POINT_CLOUD_DRAWABLE_H_

View File

@@ -55,9 +55,10 @@ const std::string kPointCloudVertexShader =
const std::string kPointCloudFragmentShader = const std::string kPointCloudFragmentShader =
"precision mediump float;\n" "precision mediump float;\n"
"precision mediump int;\n" "precision mediump int;\n"
"uniform float u_gain;\n"
"varying vec3 v_color;\n" "varying vec3 v_color;\n"
"void main() {\n" "void main() {\n"
" gl_FragColor = vec4(v_color.z, v_color.y, v_color.x, 1.0);\n" " gl_FragColor = vec4(v_color.z*u_gain, v_color.y*u_gain, v_color.x*u_gain, 1.0);\n"
"}\n"; "}\n";
const std::string kTextureMeshVertexShader = const std::string kTextureMeshVertexShader =
@@ -75,9 +76,13 @@ const std::string kTextureMeshFragmentShader =
"precision mediump float;\n" "precision mediump float;\n"
"precision mediump int;\n" "precision mediump int;\n"
"uniform sampler2D u_Texture;\n" "uniform sampler2D u_Texture;\n"
"uniform float u_gain;\n"
"varying vec2 v_TexCoordinate;\n" "varying vec2 v_TexCoordinate;\n"
"void main() {\n" "void main() {\n"
" gl_FragColor = texture2D(u_Texture, v_TexCoordinate);\n" " gl_FragColor = texture2D(u_Texture, v_TexCoordinate);\n"
" gl_FragColor.x *= u_gain;\n"
" gl_FragColor.y *= u_gain;\n"
" gl_FragColor.z *= u_gain;\n"
"}\n"; "}\n";
const std::string kGraphVertexShader = const std::string kGraphVertexShader =
@@ -109,6 +114,7 @@ Scene::Scene() :
trace_(0), trace_(0),
graph_(0), graph_(0),
graphVisible_(true), graphVisible_(true),
gridVisible_(true),
traceVisible_(true), traceVisible_(true),
currentPose_(0), currentPose_(0),
cloud_shader_program_(0), cloud_shader_program_(0),
@@ -116,6 +122,7 @@ Scene::Scene() :
graph_shader_program_(0), graph_shader_program_(0),
mapRendering_(true), mapRendering_(true),
meshRendering_(true), meshRendering_(true),
meshRenderingTexture_(true),
pointSize_(3.0f) {} pointSize_(3.0f) {}
Scene::~Scene() {DeleteResources();} Scene::~Scene() {DeleteResources();}
@@ -250,7 +257,7 @@ int Scene::Render() {
} }
else else
{ {
// In third person or top down more, we follow the camera movement. // In third person or top down mode, we follow the camera movement.
gesture_camera_->SetAnchorPosition(position, rotation); gesture_camera_->SetAnchorPosition(position, rotation);
frustum_->SetPosition(position); frustum_->SetPosition(position);
@@ -275,9 +282,11 @@ int Scene::Render() {
} }
} }
if(gridVisible_)
grid_->Render(gesture_camera_->GetProjectionMatrix(), {
gesture_camera_->GetViewMatrix()); grid_->Render(gesture_camera_->GetProjectionMatrix(),
gesture_camera_->GetViewMatrix());
}
bool frustumCulling = true; bool frustumCulling = true;
int cloudDrawn=0; int cloudDrawn=0;
@@ -327,7 +336,7 @@ int Scene::Render() {
for(unsigned int i=0; i<indices->size(); ++i) for(unsigned int i=0; i<indices->size(); ++i)
{ {
++cloudDrawn; ++cloudDrawn;
pointClouds_.find(ids[indices->at(i)])->second->Render(gesture_camera_->GetProjectionMatrix(), gesture_camera_->GetViewMatrix(), meshRendering_, pointSize_); pointClouds_.find(ids[indices->at(i)])->second->Render(gesture_camera_->GetProjectionMatrix(), gesture_camera_->GetViewMatrix(), meshRendering_, pointSize_, meshRenderingTexture_);
} }
} }
} }
@@ -338,7 +347,7 @@ int Scene::Render() {
if((mapRendering_ || iter->first < 0) && iter->second->isVisible()) if((mapRendering_ || iter->first < 0) && iter->second->isVisible())
{ {
++cloudDrawn; ++cloudDrawn;
iter->second->Render(gesture_camera_->GetProjectionMatrix(), gesture_camera_->GetViewMatrix(), meshRendering_, pointSize_); iter->second->Render(gesture_camera_->GetProjectionMatrix(), gesture_camera_->GetViewMatrix(), meshRendering_, pointSize_, meshRenderingTexture_);
} }
} }
} }
@@ -400,6 +409,11 @@ void Scene::setGraphVisible(bool visible)
graphVisible_ = visible; graphVisible_ = visible;
} }
void Scene::setGridVisible(bool visible)
{
gridVisible_ = visible;
}
void Scene::setTraceVisible(bool visible) void Scene::setTraceVisible(bool visible)
{ {
traceVisible_ = visible; traceVisible_ = visible;
@@ -409,11 +423,10 @@ void Scene::setTraceVisible(bool visible)
void Scene::addCloud( void Scene::addCloud(
int id, int id,
const pcl::PointCloud<pcl::PointXYZRGB>::Ptr & cloud, const pcl::PointCloud<pcl::PointXYZRGB>::Ptr & cloud,
const std::vector<pcl::Vertices> & polygons, const pcl::IndicesPtr & indices,
const rtabmap::Transform & pose, const rtabmap::Transform & pose)
const cv::Mat & image)
{ {
LOGI("addOrUpdateCloud cloud %d", id); LOGI("add cloud %d", id);
std::map<int, PointCloudDrawable*>::iterator iter=pointClouds_.find(id); std::map<int, PointCloudDrawable*>::iterator iter=pointClouds_.find(id);
if(iter != pointClouds_.end()) if(iter != pointClouds_.end())
{ {
@@ -427,8 +440,33 @@ void Scene::addCloud(
cloud_shader_program_, cloud_shader_program_,
texture_mesh_shader_program_, texture_mesh_shader_program_,
cloud, cloud,
polygons, indices,
image); 1.0f);
drawable->setPose(pose);
pointClouds_.insert(std::make_pair(id, drawable));
}
void Scene::addMesh(
int id,
const Mesh & mesh,
const cv::Mat & texture,
const rtabmap::Transform & pose)
{
LOGI("add mesh %d", id);
std::map<int, PointCloudDrawable*>::iterator iter=pointClouds_.find(id);
if(iter != pointClouds_.end())
{
delete iter->second;
pointClouds_.erase(iter);
}
//create
UASSERT(cloud_shader_program_ != 0 && texture_mesh_shader_program_!=0);
PointCloudDrawable * drawable = new PointCloudDrawable(
cloud_shader_program_,
texture_mesh_shader_program_,
mesh,
texture);
drawable->setPose(pose); drawable->setPose(pose);
pointClouds_.insert(std::make_pair(id, drawable)); pointClouds_.insert(std::make_pair(id, drawable));
} }
@@ -458,7 +496,30 @@ bool Scene::hasCloud(int id) const
return pointClouds_.find(id) != pointClouds_.end(); return pointClouds_.find(id) != pointClouds_.end();
} }
bool Scene::hasTexture(int id) const
{
return pointClouds_.find(id) != pointClouds_.end() && pointClouds_.at(id)->hasTexture();
}
std::set<int> Scene::getAddedClouds() const std::set<int> Scene::getAddedClouds() const
{ {
return uKeysSet(pointClouds_); return uKeysSet(pointClouds_);
} }
void Scene::updateCloudPolygons(int id, const std::vector<pcl::Vertices> & polygons)
{
std::map<int, PointCloudDrawable*>::iterator iter=pointClouds_.find(id);
if(iter != pointClouds_.end())
{
iter->second->updatePolygons(polygons);
}
}
void Scene::updateMesh(int id, const Mesh & mesh, const cv::Mat & texture)
{
std::map<int, PointCloudDrawable*>::iterator iter=pointClouds_.find(id);
if(iter != pointClouds_.end())
{
iter->second->updateMesh(mesh, texture);
}
}

View File

@@ -94,24 +94,35 @@ class Scene {
const std::multimap<int, rtabmap::Link> & links); const std::multimap<int, rtabmap::Link> & links);
void setGraphVisible(bool visible); void setGraphVisible(bool visible);
void setGridVisible(bool visible);
void setTraceVisible(bool visible); void setTraceVisible(bool visible);
void addCloud( void addCloud(
int id, int id,
const pcl::PointCloud<pcl::PointXYZRGB>::Ptr & cloud, const pcl::PointCloud<pcl::PointXYZRGB>::Ptr & cloud,
const std::vector<pcl::Vertices> & polygons, const pcl::IndicesPtr & indices,
const rtabmap::Transform & pose, const rtabmap::Transform & pose);
const cv::Mat & image = cv::Mat()); void addMesh(
int id,
const Mesh & mesh,
const cv::Mat & texture,
const rtabmap::Transform & pose);
void setCloudPose(int id, const rtabmap::Transform & pose); void setCloudPose(int id, const rtabmap::Transform & pose);
void setCloudVisible(int id, bool visible); void setCloudVisible(int id, bool visible);
bool hasCloud(int id) const; bool hasCloud(int id) const;
bool hasTexture(int id) const;
std::set<int> getAddedClouds() const; std::set<int> getAddedClouds() const;
void updateCloudPolygons(int id, const std::vector<pcl::Vertices> & polygons);
void updateMesh(int id, const Mesh & mesh, const cv::Mat & texture);
void setMapRendering(bool enabled) {mapRendering_ = enabled;} void setMapRendering(bool enabled) {mapRendering_ = enabled;}
void setMeshRendering(bool enabled) {meshRendering_ = enabled;} void setMeshRendering(bool enabled, bool withTexture) {meshRendering_ = enabled; meshRenderingTexture_ = withTexture;}
void setPointSize(float size) {pointSize_ = size;} void setPointSize(float size) {pointSize_ = size;}
bool isMeshRendering() const {return meshRendering_;}
bool isMeshTexturing() const {return meshRendering_ && meshRenderingTexture_;}
private: private:
// Camera object that allows user to use touch input to interact with. // Camera object that allows user to use touch input to interact with.
tango_gl::GestureCamera* gesture_camera_; tango_gl::GestureCamera* gesture_camera_;
@@ -129,6 +140,7 @@ class Scene {
tango_gl::Trace* trace_; tango_gl::Trace* trace_;
GraphDrawable * graph_; GraphDrawable * graph_;
bool graphVisible_; bool graphVisible_;
bool gridVisible_;
bool traceVisible_; bool traceVisible_;
std::map<int, PointCloudDrawable*> pointClouds_; std::map<int, PointCloudDrawable*> pointClouds_;
@@ -142,6 +154,7 @@ class Scene {
bool mapRendering_; bool mapRendering_;
bool meshRendering_; bool meshRendering_;
bool meshRenderingTexture_;
float pointSize_; float pointSize_;
}; };

View File

@@ -16,6 +16,7 @@
#include "tango-gl/gesture_camera.h" #include "tango-gl/gesture_camera.h"
#include "tango-gl/util.h" #include "tango-gl/util.h"
#include "glm/gtx/quaternion.hpp"
namespace { namespace {
// Render camera observation distance in third person camera mode. // Render camera observation distance in third person camera mode.
@@ -30,8 +31,14 @@ const float kTopDownCameraDist = 5.0f;
// Zoom in speed. // Zoom in speed.
const float kZoomSpeed = 10.0f; const float kZoomSpeed = 10.0f;
// Move speed
const float kMoveSpeed = 10.0f;
// Rotation speed
const float kRotationSpeed = 2.0f;
// Min/max clamp value of camera observation distance. // Min/max clamp value of camera observation distance.
const float kCamViewMinDist = 1.0f; const float kCamViewMinDist = .1f;
const float kCamViewMaxDist = 100.f; const float kCamViewMaxDist = 100.f;
// FOV set up values. // FOV set up values.
@@ -70,8 +77,8 @@ void GestureCamera::OnTouchEvent(int touch_count, TouchEvent event, float x0,
break; break;
} }
case kTouchMove: { case kTouchMove: {
float rotation_x = touch0_start_position_.y - y0; float rotation_x = (touch0_start_position_.y - y0) * kRotationSpeed;
float rotation_y = touch0_start_position_.x - x0; float rotation_y = (touch0_start_position_.x - x0) * kRotationSpeed;
cam_cur_angle_.x = cam_start_angle_.x + rotation_x; cam_cur_angle_.x = cam_start_angle_.x + rotation_x;
cam_cur_angle_.y = cam_start_angle_.y + rotation_y; cam_cur_angle_.y = cam_start_angle_.y + rotation_y;
@@ -88,17 +95,30 @@ void GestureCamera::OnTouchEvent(int touch_count, TouchEvent event, float x0,
float abs_y = y0 - y1; float abs_y = y0 - y1;
start_touch_dist_ = std::sqrt(abs_x * abs_x + abs_y * abs_y); start_touch_dist_ = std::sqrt(abs_x * abs_x + abs_y * abs_y);
cam_start_dist_ = GetPosition().z; cam_start_dist_ = GetPosition().z;
// center touch
touch0_start_position_.x = (x0+x1)/2.0f;
touch0_start_position_.y = (y0+y1)/2.0f;
break; break;
} }
case kTouchMove: { case kTouchMove: {
float abs_x = x0 - x1; float abs_x = x0 - x1;
float abs_y = y0 - y1; float abs_y = y0 - y1;
float dist = float dist = start_touch_dist_ - std::sqrt(abs_x * abs_x + abs_y * abs_y);
start_touch_dist_ - std::sqrt(abs_x * abs_x + abs_y * abs_y);
cam_cur_dist_ = cam_cur_dist_ = tango_gl::util::Clamp(cam_start_dist_ + dist * kZoomSpeed,
tango_gl::util::Clamp(cam_start_dist_ + dist * kZoomSpeed,
kCamViewMinDist, kCamViewMaxDist); kCamViewMinDist, kCamViewMaxDist);
glm::vec2 touch_center_position((x0+x1)/2.0f, (y0+y1)/2.0f);
glm::vec2 offset;
offset.x = (touch_center_position.x - touch0_start_position_.x) * kMoveSpeed;
offset.y = (touch_center_position.y - touch0_start_position_.y) * kMoveSpeed;
touch0_start_position_ = touch_center_position;
StartCameraToCurrentTransform(); StartCameraToCurrentTransform();
anchor_offset_ += glm::rotate(cam_parent_transform_->GetRotation(), glm::vec3(-offset.x, offset.y, 0));
break; break;
} }
default: { break; } default: { break; }
@@ -126,7 +146,10 @@ Segment GestureCamera::GetSegmentFromTouch(float normalized_x,
} }
void GestureCamera::SetAnchorPosition(const glm::vec3& pos, const glm::quat & rotation) { void GestureCamera::SetAnchorPosition(const glm::vec3& pos, const glm::quat & rotation) {
cam_parent_transform_->SetPosition(pos); // Anchor position
cam_parent_transform_->SetPosition(pos+anchor_offset_);
// Anchor rotation
if(camera_type_ == kThirdPersonFollow) if(camera_type_ == kThirdPersonFollow)
{ {
cam_cur_target_rot_ = rotation; cam_cur_target_rot_ = rotation;
@@ -145,6 +168,7 @@ void GestureCamera::SetCameraType(CameraType camera_index) {
SetPosition(glm::vec3(0.0f, 0.0f, 0.0f)); SetPosition(glm::vec3(0.0f, 0.0f, 0.0f));
SetRotation(glm::quat(1.0f, 0.0f, 0.0f, 0.0f)); SetRotation(glm::quat(1.0f, 0.0f, 0.0f, 0.0f));
cam_cur_dist_ = 0.0f; cam_cur_dist_ = 0.0f;
anchor_offset_ = glm::vec3(0.0f,0.0f,0.0f);
cam_cur_angle_.x = 0.0f; cam_cur_angle_.x = 0.0f;
cam_cur_angle_.y = 0.0f; cam_cur_angle_.y = 0.0f;
cam_cur_target_rot_ = glm::quat(1,0,0,0); cam_cur_target_rot_ = glm::quat(1,0,0,0);
@@ -157,6 +181,7 @@ void GestureCamera::SetCameraType(CameraType camera_index) {
SetPosition(glm::vec3(0.0f, 0.0f, 0.0f)); SetPosition(glm::vec3(0.0f, 0.0f, 0.0f));
SetRotation(glm::quat(1.0f, 0.0f, 0.0f, 0.0f)); SetRotation(glm::quat(1.0f, 0.0f, 0.0f, 0.0f));
cam_cur_dist_ = kThirdPersonFollow?kThirdPersonFollowCameraDist:kThirdPersonCameraDist; cam_cur_dist_ = kThirdPersonFollow?kThirdPersonFollowCameraDist:kThirdPersonCameraDist;
anchor_offset_ = glm::vec3(0.0f,0.0f,0.0f);
cam_cur_angle_.x = -M_PI / 4.0f; cam_cur_angle_.x = -M_PI / 4.0f;
cam_cur_angle_.y = kThirdPersonFollow?0:M_PI / 4.0f; cam_cur_angle_.y = kThirdPersonFollow?0:M_PI / 4.0f;
cam_cur_target_rot_ = glm::quat(1,0,0,0); cam_cur_target_rot_ = glm::quat(1,0,0,0);
@@ -167,6 +192,7 @@ void GestureCamera::SetCameraType(CameraType camera_index) {
SetPosition(glm::vec3(0.0f, 0.0f, 0.0f)); SetPosition(glm::vec3(0.0f, 0.0f, 0.0f));
SetRotation(glm::quat(1.0f, 0.0f, 0.0f, 0.0f)); SetRotation(glm::quat(1.0f, 0.0f, 0.0f, 0.0f));
cam_cur_dist_ = kTopDownCameraDist; cam_cur_dist_ = kTopDownCameraDist;
anchor_offset_ = glm::vec3(0.0f,0.0f,0.0f);
cam_cur_angle_.x = -M_PI / 2.0f; cam_cur_angle_.x = -M_PI / 2.0f;
cam_cur_angle_.y = 0.0f; cam_cur_angle_.y = 0.0f;
cam_cur_target_rot_ = glm::quat(1,0,0,0); cam_cur_target_rot_ = glm::quat(1,0,0,0);
@@ -179,9 +205,12 @@ void GestureCamera::SetCameraType(CameraType camera_index) {
void GestureCamera::StartCameraToCurrentTransform() void GestureCamera::StartCameraToCurrentTransform()
{ {
//Anchor rotation
glm::quat parent_cam_rot = glm::rotate(cam_cur_target_rot_, cam_cur_angle_.y, glm::vec3(0, 1, 0)); glm::quat parent_cam_rot = glm::rotate(cam_cur_target_rot_, cam_cur_angle_.y, glm::vec3(0, 1, 0));
parent_cam_rot = glm::rotate(parent_cam_rot, cam_cur_angle_.x, glm::vec3(1, 0, 0)); parent_cam_rot = glm::rotate(parent_cam_rot, cam_cur_angle_.x, glm::vec3(1, 0, 0));
SetPosition(glm::vec3(0.0f, 0.0f, cam_cur_dist_));
cam_parent_transform_->SetRotation(parent_cam_rot); cam_parent_transform_->SetRotation(parent_cam_rot);
//Camera position
SetPosition(glm::vec3(0, 0, cam_cur_dist_));
} }
} // namespace tango_gl } // namespace tango_gl

View File

@@ -76,6 +76,7 @@ class GestureCamera : public Camera {
float cam_start_dist_; float cam_start_dist_;
float cam_cur_dist_; float cam_cur_dist_;
glm::vec3 anchor_offset_;
float start_touch_dist_; float start_touch_dist_;
float cur_touch_dist_; float cur_touch_dist_;

View File

@@ -32,13 +32,22 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include <android/log.h> #include <android/log.h>
#include <rtabmap/utilite/UEventsHandler.h> #include <rtabmap/utilite/UEventsHandler.h>
#include <rtabmap/utilite/ULogger.h> #include <rtabmap/utilite/ULogger.h>
#include <rtabmap/core/CameraModel.h>
#include <tango-gl/util.h> #include <tango-gl/util.h>
#include <pcl/point_cloud.h>
#include <pcl/point_types.h>
#include <pcl/Vertices.h>
#include <pcl/pcl_base.h>
class LogHandler : public UEventsHandler class LogHandler : public UEventsHandler
{ {
public: public:
LogHandler() LogHandler()
{ {
ULogger::setLevel(ULogger::kWarning);
ULogger::setEventLevel(ULogger::kWarning);
ULogger::setPrintThreadId(true);
registerToEventsManager(); registerToEventsManager();
} }
protected: protected:
@@ -69,21 +78,26 @@ protected:
}; };
static const rtabmap::Transform opengl_world_T_tango_world( static const rtabmap::Transform opengl_world_T_tango_world(
1.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f,
0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f,
0.0f, -1.0f, 0.0f, 0.0f); 0.0f, -1.0f, 0.0f, 0.0f);
static const rtabmap::Transform depth_camera_T_opengl_camera( static const rtabmap::Transform rtabmap_world_T_tango_world(
1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f,
0.0f, -1.0f, 0.0f, 0.0f, -1.0f, 0.0f, 0.0f, 0.0f,
0.0f, 0.0f, -1.0f, 0.0f); 0.0f, 0.0f, 1.0f, 0.0f);
static const rtabmap::Transform tango_device_T_rtabmap_device(
0.0f, -1.0f, 0.0f, 0.0f,
0.0f, 0.0f, 1.0f, 0.0f,
-1.0f, 0.0f, 0.0f, 0.0f);
static const rtabmap::Transform opengl_world_T_rtabmap_world( static const rtabmap::Transform opengl_world_T_rtabmap_world(
0.0f, -1.0f, 0.0f, 0.0f, 0.0f, -1.0f, 0.0f, 0.0f,
0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f,
-1.0f, 0.0f, 0.0f, 0.0f); -1.0f, 0.0f, 0.0f, 0.0f);
static const rtabmap::Transform rtabmap_world_T_opengl_world( static const rtabmap::Transform rtabmap_device_T_opengl_device(
0.0f, 0.0f, -1.0f, 0.0f, 0.0f, 0.0f, -1.0f, 0.0f,
-1.0f, 0.0f, 0.0f, 0.0f, -1.0f, 0.0f, 0.0f, 0.0f,
0.0f, 1.0f, 0.0f, 0.0f); 0.0f, 1.0f, 0.0f, 0.0f);
@@ -129,4 +143,15 @@ inline rtabmap::Transform glmToTransform(const glm::mat4 & mat)
return transform; return transform;
} }
struct Mesh
{
pcl::PointCloud<pcl::PointXYZRGB>::Ptr cloud; // organized cloud
pcl::IndicesPtr indices;
std::vector<pcl::Vertices> polygons;
rtabmap::Transform pose; // in rtabmap coordinates
bool visible;
rtabmap::CameraModel cameraModel;
float gain;
};
#endif /* UTIL_H_ */ #endif /* UTIL_H_ */

View File

@@ -8,15 +8,22 @@
<group android:id="@+id/group_actions"> <group android:id="@+id/group_actions">
<item android:id="@+id/post_processing" android:title="Post-Processing..."> <item android:id="@+id/post_processing" android:title="Post-Processing...">
<menu> <menu>
<group android:id="@+id/group_post_processing"> <item android:id="@+id/post_processing_standard" android:title="Standard Optimization" />
<item android:id="@+id/detect_more_loop_closures" android:title="Detect More Loop Closures" /> <item android:id="@+id/post_processing_advanced" android:title="Advanced..." >
<item android:id="@+id/global_graph_optimization" android:title="Global Graph Optimization" /> <menu>
<item android:id="@+id/sba" android:title="Bundle Adjustement" /> <item android:id="@+id/global_graph_optimization" android:title="Global Graph Optimization" />
</group> <item android:id="@+id/detect_more_loop_closures" android:title="Detect More Loop Closures" />
<item android:id="@+id/icp_refining" android:title="ICP Refining" />
<item android:id="@+id/gain_compensation_fast" android:title="Adjust Colors (Fast)" />
<item android:id="@+id/gain_compensation_full" android:title="Adjust Colors (Full)" />
<item android:id="@+id/bilateral_filtering" android:title="Mesh Smoothing" />
<item android:id="@+id/sba" android:title="Bundle Adjustement" />
<item android:id="@+id/polygons_filtering" android:title="Noise Filtering" />
</menu>
</item>
</menu> </menu>
</item> </item>
<item android:id="@+id/open" android:title="Open"/> <item android:id="@+id/open" android:title="Open"/>
<item android:id="@+id/save" android:title="Save"/>
<item android:id="@+id/export" android:title="Export..."> <item android:id="@+id/export" android:title="Export...">
<menu> <menu>
<group android:id="@+id/group_export"> <group android:id="@+id/group_export">
@@ -25,20 +32,31 @@
</group> </group>
</menu> </menu>
</item> </item>
<item android:id="@+id/save" android:title="Save"/>
<item android:id="@+id/reset" android:title="Reset"/> <item android:id="@+id/reset" android:title="Reset"/>
<item android:id="@+id/menu_rendering_settings" android:title="Rendering Options..."> <item android:id="@+id/menu_rendering_settings" android:title="Rendering Options...">
<menu > <menu >
<group android:id="@+id/group_rendering_visibility" android:checkableBehavior="all"> <group android:id="@+id/group_rendering_visibility" android:checkableBehavior="all">
<item android:id="@+id/debug" android:checked="false" android:title="Debug" /> <item android:id="@+id/debug" android:checked="false" android:title="Debug" />
<item android:id="@+id/mesh_rendering" android:checked="true" android:title="Mesh Rendering" /> <item android:id="@+id/menu_rendering" android:checkable="false" android:title="Mesh Rendering..." >
<menu>
<group android:checkableBehavior="single">
<item android:id="@+id/point_cloud" android:title="Point Cloud" />
<item android:id="@+id/mesh" android:title="Mesh" />
<item android:id="@+id/texture_mesh" android:checked="true" android:title="Texture Mesh" />
</group>
<item android:id="@+id/mesh_decimation" android:checkable="false" android:title="Mesh Decimation..." />
<item android:id="@+id/mesh_angle_tolerance" android:checkable="false" android:title="Mesh Angle Tolerance..." />
<item android:id="@+id/mesh_triangle_size" android:checkable="false" android:title="Mesh Triangle Size..." />
<item android:id="@+id/max_depth" android:checkable="false" android:title="Max Depth..." />
</menu>
</item>
<item android:id="@+id/map_shown" android:checked="true" android:title="Map Visible" /> <item android:id="@+id/map_shown" android:checked="true" android:title="Map Visible" />
<item android:id="@+id/odom_shown" android:checked="true" android:title="Odom Visible" /> <item android:id="@+id/odom_shown" android:checked="true" android:title="Odom Visible" />
<item android:id="@+id/graph_visible" android:checked="true" android:title="Graph Visible" /> <item android:id="@+id/graph_visible" android:checked="true" android:title="Graph Visible" />
<item android:id="@+id/auto_exposure" android:checked="false" android:title="Auto Exposure" /> <item android:id="@+id/grid_visible" android:checked="true" android:title="Grid Visible" />
<item android:id="@+id/max_depth" android:checkable="false" android:title="Cloud/Mesh Max Depth..." /> <item android:id="@+id/graph_optimization" android:checked="true" android:title="Optimized Graph" />
<item android:id="@+id/mesh_angle_tolerance" android:checkable="false" android:title="Mesh Angle Tolerance..." />
<item android:id="@+id/mesh_triangle_size" android:checkable="false" android:title="Mesh Triangle Size..." />
</group> </group>
</menu> </menu>
</item> </item>
@@ -47,9 +65,12 @@
<group android:id="@+id/group_mapping_visibility" android:checkableBehavior="all"> <group android:id="@+id/group_mapping_visibility" android:checkableBehavior="all">
<item android:id="@+id/localization_mode" android:checked="false" android:title="Localization Mode" /> <item android:id="@+id/localization_mode" android:checked="false" android:title="Localization Mode" />
<item android:id="@+id/trajectory_mode" android:checked="false" android:title="Trajectory Mode" /> <item android:id="@+id/trajectory_mode" android:checked="false" android:title="Trajectory Mode" />
<item android:id="@+id/graph_optimization" android:checked="true" android:title="Optimized Graph" /> <item android:id="@+id/append" android:checked="true" android:title="Append Mode" />
<item android:id="@+id/nodes_filtering" android:checked="false" android:title="Nodes Filtering" /> <item android:id="@+id/nodes_filtering" android:checked="false" android:title="Nodes Filtering" />
<item android:id="@+id/resolution" android:checked="false" android:title="720p Mode" /> <item android:id="@+id/drift_correction" android:checked="false" android:title="Drift Correction" />
<item android:id="@+id/auto_exposure" android:checked="true" android:title="Auto Exposure" />
<item android:id="@+id/resolution" android:checked="false" android:title="HD Mode" />
<item android:id="@+id/data_recorder" android:checked="false" android:title="Data Recorder Mode" />
<item android:id="@+id/menu_param_settings" android:checkable="false" android:title="Parameters..."> <item android:id="@+id/menu_param_settings" android:checkable="false" android:title="Parameters...">
<menu > <menu >
<item android:id="@+id/update_rate" android:title="Map Update Rate..." /> <item android:id="@+id/update_rate" android:title="Map Update Rate..." />

View File

@@ -2,6 +2,9 @@ package com.introlab.rtabmap;
import java.io.File; import java.io.File;
import java.io.FilenameFilter; import java.io.FilenameFilter;
import java.text.SimpleDateFormat;
import java.util.Arrays;
import java.util.Date;
import android.app.Activity; import android.app.Activity;
import android.app.AlertDialog; import android.app.AlertDialog;
@@ -49,10 +52,10 @@ public class RTABMapActivity extends Activity implements OnClickListener {
private static final String TAG = RTABMapActivity.class.getSimpleName(); private static final String TAG = RTABMapActivity.class.getSimpleName();
// The minimum Tango Core version required from this application. // The minimum Tango Core version required from this application.
private static final int MIN_TANGO_CORE_VERSION = 6804; private static final int MIN_TANGO_CORE_VERSION = 9377;
// The package name of Tang Core, used for checking minimum Tango Core version. // The package name of Tang Core, used for checking minimum Tango Core version.
private static final String TANGO_PACKAGE_NAME = "com.projecttango.tango"; private static final String TANGO_PACKAGE_NAME = "com.google.tango";
public static final String EXTRA_KEY_PERMISSIONTYPE = "PERMISSIONTYPE"; public static final String EXTRA_KEY_PERMISSIONTYPE = "PERMISSIONTYPE";
public static final String EXTRA_VALUE_ADF = "ADF_LOAD_SAVE_PERMISSION"; public static final String EXTRA_VALUE_ADF = "ADF_LOAD_SAVE_PERMISSION";
@@ -66,7 +69,9 @@ public class RTABMapActivity extends Activity implements OnClickListener {
// Screen size for normalizing the touch input for orbiting the render camera. // Screen size for normalizing the touch input for orbiting the render camera.
private Point mScreenSize = new Point(); private Point mScreenSize = new Point();
private boolean mPauseFirstTime = true;
private boolean mOnPause = false;
private MenuItem mItemPause; private MenuItem mItemPause;
private MenuItem mItemSave; private MenuItem mItemSave;
private MenuItem mItemOpen; private MenuItem mItemOpen;
@@ -74,21 +79,26 @@ public class RTABMapActivity extends Activity implements OnClickListener {
private MenuItem mItemExport; private MenuItem mItemExport;
private MenuItem mItemLocalizationMode; private MenuItem mItemLocalizationMode;
private MenuItem mItemTrajectoryMode; private MenuItem mItemTrajectoryMode;
private MenuItem mItemAppendMode;
private MenuItem mItemRenderingPointCloud;
private MenuItem mItemRenderingMesh;
private MenuItem mItemRenderingTextureMesh;
private MenuItem mItemDataRecorderMode;
private String mOpenedDatabasePath = ""; private String mOpenedDatabasePath = "";
private String mTempDatabasePath = "";
private String mNewDatabasePath = "";
private String mWorkingDirectory = ""; private String mWorkingDirectory = "";
private int mMaxDepthIndex = 5; private int mMaxDepthIndex = 5;
private int mMeshAngleToleranceIndex = 1; private int mMeshDecimationIndex = 0;
private int mMeshAngleToleranceIndex = 2;
private int mMeshTriangleSizeIndex = 0; private int mMeshTriangleSizeIndex = 0;
private int mParamUpdateRateHzIndex = 1; private int mParamUpdateRateHzIndex = 1;
private int mParamTimeThrMsIndex = 4; private int mParamTimeThrMsIndex = 4;
private int mParamMaxFeaturesIndex = 4; private int mParamMaxFeaturesIndex = 2;
private int mParamLoopThrMsIndex = 1; private int mParamLoopThrMsIndex = 1;
private int mParamOptimizeErrorIndex = 3; private int mParamOptimizeErrorIndex = 4;
final String[] mUpdateRateValues = {"0.5", "1", "2", "Max"}; final String[] mUpdateRateValues = {"0.5", "1", "2", "Max"};
final String[] mTimeThrValues = {"400", "500", "600", "700", "800", "900", "1000", "1100", "1200", "1300", "1400", "1500", "No Limit"}; final String[] mTimeThrValues = {"400", "500", "600", "700", "800", "900", "1000", "1100", "1200", "1300", "1400", "1500", "No Limit"};
@@ -99,6 +109,7 @@ public class RTABMapActivity extends Activity implements OnClickListener {
private LinearLayout mLayoutDebug; private LinearLayout mLayoutDebug;
private int mTotalLoopClosures = 0; private int mTotalLoopClosures = 0;
private boolean mMapIsEmpty = false;
private Toast mToast = null; private Toast mToast = null;
@@ -124,7 +135,7 @@ public class RTABMapActivity extends Activity implements OnClickListener {
protected void onCreate(Bundle savedInstanceState) { protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState); super.onCreate(savedInstanceState);
setTitle(R.string.menu_name); setTitle(R.string.menu_name);
// Query screen size, the screen size is used for computing the normalized // Query screen size, the screen size is used for computing the normalized
// touch point. // touch point.
Display display = getWindowManager().getDefaultDisplay(); Display display = getWindowManager().getDefaultDisplay();
@@ -156,6 +167,7 @@ public class RTABMapActivity extends Activity implements OnClickListener {
mLayoutDebug.setVisibility(LinearLayout.GONE); mLayoutDebug.setVisibility(LinearLayout.GONE);
mProgressDialog = new ProgressDialog(this); mProgressDialog = new ProgressDialog(this);
mProgressDialog.setCanceledOnTouchOutside(false);
mRenderer.setProgressDialog(mProgressDialog); mRenderer.setProgressDialog(mProgressDialog);
// Check if the Tango Core is out dated. // Check if the Tango Core is out dated.
@@ -166,8 +178,6 @@ public class RTABMapActivity extends Activity implements OnClickListener {
} }
mOpenedDatabasePath = ""; mOpenedDatabasePath = "";
mTempDatabasePath = "";
mNewDatabasePath = "";
mWorkingDirectory = ""; mWorkingDirectory = "";
mTotalLoopClosures = 0; mTotalLoopClosures = 0;
@@ -177,13 +187,6 @@ public class RTABMapActivity extends Activity implements OnClickListener {
mWorkingDirectory = extStore.getAbsolutePath() + "/" + getString(R.string.app_name) + "/"; mWorkingDirectory = extStore.getAbsolutePath() + "/" + getString(R.string.app_name) + "/";
extStore = new File(mWorkingDirectory); extStore = new File(mWorkingDirectory);
extStore.mkdirs(); extStore.mkdirs();
mTempDatabasePath = mWorkingDirectory + "rtabmap.tmp.db";
extStore = new File(mTempDatabasePath);
if(extStore.exists())
{
extStore.delete();
}
} }
else else
{ {
@@ -194,7 +197,7 @@ public class RTABMapActivity extends Activity implements OnClickListener {
} }
RTABMapLib.onCreate(this); RTABMapLib.onCreate(this);
RTABMapLib.openDatabase(mTempDatabasePath); RTABMapLib.openEmptyDatabase();
} }
@Override @Override
@@ -213,6 +216,21 @@ public class RTABMapActivity extends Activity implements OnClickListener {
@Override @Override
protected void onResume() { protected void onResume() {
super.onResume(); super.onResume();
mProgressDialog.setTitle("");
mProgressDialog.setMessage(String.format("Hold Tight! Initializing Tango Service..."));
mProgressDialog.show();
if(mOnPause)
{
mToast.makeText(this, "Mapping is paused!", mToast.LENGTH_LONG).show();
}
else
{
mToast.makeText(this, "Tip: If the camera is still drifting just after the mapping has started, do \"Reset\".", mToast.LENGTH_LONG).show();
}
mOnPause = false;
TangoInitializationHelper.bindTangoService(this, mTangoServiceConnection); TangoInitializationHelper.bindTangoService(this, mTangoServiceConnection);
@@ -221,16 +239,6 @@ public class RTABMapActivity extends Activity implements OnClickListener {
if (Tango.hasPermission(this, Tango.PERMISSIONTYPE_MOTION_TRACKING)) { if (Tango.hasPermission(this, Tango.PERMISSIONTYPE_MOTION_TRACKING)) {
mGLView.onResume(); mGLView.onResume();
mTotalLoopClosures = 0;
if(mItemOpen != null)
{
mItemOpen.setEnabled(false);
mItemPause.setChecked(false);
mItemSave.setEnabled(false);
mItemExport.setEnabled(false);
mItemPostProcessing.setEnabled(false);
}
} else { } else {
Log.i(TAG, String.format("Asking for motion tracking permission")); Log.i(TAG, String.format("Asking for motion tracking permission"));
@@ -243,14 +251,20 @@ public class RTABMapActivity extends Activity implements OnClickListener {
@Override @Override
protected void onPause() { protected void onPause() {
super.onPause(); super.onPause();
// This deletes OpenGL context!
mGLView.onPause(); mGLView.onPause();
// Delete all the non-OpenGl resources. mOnPause = true;
RTABMapLib.onPause(); RTABMapLib.onPause();
mOpenedDatabasePath = "";
RTABMapLib.openDatabase(mTempDatabasePath);
unbindService(mTangoServiceConnection); unbindService(mTangoServiceConnection);
if(!mItemPause.isChecked())
{
onOptionsItemSelected(mItemPause);
}
} }
@Override @Override
@@ -316,10 +330,16 @@ public class RTABMapActivity extends Activity implements OnClickListener {
mItemExport = menu.findItem(R.id.export); mItemExport = menu.findItem(R.id.export);
mItemLocalizationMode = menu.findItem(R.id.localization_mode); mItemLocalizationMode = menu.findItem(R.id.localization_mode);
mItemTrajectoryMode = menu.findItem(R.id.trajectory_mode); mItemTrajectoryMode = menu.findItem(R.id.trajectory_mode);
mItemAppendMode = menu.findItem(R.id.append);
mItemRenderingPointCloud = menu.findItem(R.id.point_cloud);
mItemRenderingMesh = menu.findItem(R.id.mesh);
mItemRenderingTextureMesh = menu.findItem(R.id.texture_mesh);
mItemDataRecorderMode = menu.findItem(R.id.data_recorder);
mItemSave.setEnabled(false); mItemSave.setEnabled(false);
mItemExport.setEnabled(false); mItemExport.setEnabled(false);
mItemOpen.setEnabled(false); mItemOpen.setEnabled(false);
mItemPostProcessing.setEnabled(false); mItemPostProcessing.setEnabled(false);
mItemDataRecorderMode.setEnabled(false);
return true; return true;
} }
@@ -342,7 +362,7 @@ public class RTABMapActivity extends Activity implements OnClickListener {
{ {
if(mItemPause!=null) if(mItemPause!=null)
{ {
((TextView)findViewById(R.id.status)).setText(mItemPause.isChecked()?"Paused":mItemLocalizationMode.isChecked()?String.format("Localization (%s Hz)", mUpdateRateValues[mParamUpdateRateHzIndex]):String.format("Mapping (%s Hz)", mUpdateRateValues[mParamUpdateRateHzIndex])); ((TextView)findViewById(R.id.status)).setText(mItemPause.isChecked()?"Paused":mItemLocalizationMode.isChecked()?String.format("Localization (%s Hz)", mUpdateRateValues[mParamUpdateRateHzIndex]):mItemDataRecorderMode.isChecked()?String.format("Recording (%s Hz)", mUpdateRateValues[mParamUpdateRateHzIndex]):String.format("Mapping (%s Hz)", mUpdateRateValues[mParamUpdateRateHzIndex]));
} }
((TextView)findViewById(R.id.points)).setText(String.valueOf(points)); ((TextView)findViewById(R.id.points)).setText(String.valueOf(points));
@@ -407,108 +427,7 @@ public class RTABMapActivity extends Activity implements OnClickListener {
Log.i(TAG, String.format("rtabmapInitEventsUI() status=%d msg=%s", status, msg)); Log.i(TAG, String.format("rtabmapInitEventsUI() status=%d msg=%s", status, msg));
((TextView)findViewById(R.id.status)).setText( ((TextView)findViewById(R.id.status)).setText(
status == 1 && msg.isEmpty()?mItemPause!=null&&mItemPause.isChecked()?"Paused":mItemLocalizationMode!=null&&mItemLocalizationMode.isChecked()?"Localization":"Mapping":msg); status == 1 && msg.isEmpty()?(mItemPause!=null&&mItemPause.isChecked()?"Paused":mItemLocalizationMode!=null&&mItemLocalizationMode.isChecked()?"Localization":mItemDataRecorderMode!=null&&mItemDataRecorderMode.isChecked()?"Recording":"Mapping"):msg);
/*0=kInitializing,
1=kInitialized,
2=kClosing,
3=kClosed,
4=kInfo,
5=kError*/
if(status == 3)
{
msg = "";
if(!mNewDatabasePath.isEmpty())
{
boolean removed = true;
File outputFile = new File(mNewDatabasePath);
if(outputFile.exists())
{
removed = outputFile.delete();
}
if(removed)
{
File tempFile = new File(mTempDatabasePath);
if(tempFile.renameTo(outputFile))
{
msg = String.format("Database saved to \"%s\".", mNewDatabasePath);
Intent intent = new Intent(this, RTABMapActivity.class);
// use System.currentTimeMillis() to have a unique ID for the pending intent
PendingIntent pIntent = PendingIntent.getActivity(this, (int) System.currentTimeMillis(), intent, 0);
// build notification
// the addAction re-use the same intent to keep the example short
Notification n = new Notification.Builder(this)
.setContentTitle(getString(R.string.app_name))
.setContentText(mNewDatabasePath + " saved!")
.setSmallIcon(R.drawable.ic_launcher)
.setContentIntent(pIntent)
.setAutoCancel(true).build();
NotificationManager notificationManager =
(NotificationManager) getSystemService(NOTIFICATION_SERVICE);
notificationManager.notify(0, n);
}
else
{
msg = String.format("Failed to rename temporary database from \"%s\" to \"%s\".",
mTempDatabasePath, mNewDatabasePath);
}
}
else
{
msg = String.format("Failed to overwrite the database \"%s\". The temporary database is still correctly saved at \"%s\".",
mNewDatabasePath, mTempDatabasePath);
}
}
else if(!mOpenedDatabasePath.isEmpty())
{
msg = String.format("Database \"%s\" updated.", mOpenedDatabasePath);
}
if(!msg.isEmpty())
{
mToast.makeText(this, msg, mToast.LENGTH_LONG).show();
}
mOpenedDatabasePath = "";
mNewDatabasePath = "";
//restart a new scan by default
RTABMapLib.openDatabase(mTempDatabasePath);
((TextView)findViewById(R.id.points)).setText(String.valueOf(0));
((TextView)findViewById(R.id.polygons)).setText(String.valueOf(0));
((TextView)findViewById(R.id.nodes)).setText(String.valueOf(0));
((TextView)findViewById(R.id.words)).setText(String.valueOf(0));
((TextView)findViewById(R.id.memory)).setText(String.valueOf(Debug.getNativeHeapAllocatedSize()/(1024*1024)));
((TextView)findViewById(R.id.db_size)).setText(String.valueOf(0));
((TextView)findViewById(R.id.inliers)).setText(String.valueOf(0));
((TextView)findViewById(R.id.features)).setText(String.valueOf(0));
((TextView)findViewById(R.id.update_time)).setText(String.valueOf(0));
((TextView)findViewById(R.id.hypothesis)).setText(String.valueOf(0));
((TextView)findViewById(R.id.fps)).setText(String.valueOf(0));
mTotalLoopClosures = 0;
((TextView)findViewById(R.id.total_loop)).setText(String.valueOf(mTotalLoopClosures));
if(mItemSave!=null)
{
if(mItemPause.isChecked())
{
mItemPause.setChecked(false);
mItemOpen.setEnabled(false);
mItemPostProcessing.setEnabled(false);
mItemSave.setEnabled(false);
mItemExport.setEnabled(false);
RTABMapLib.setPausedMapping(false); // resume mapping
}
}
mProgressDialog.dismiss();
}
} }
//called from jni //called from jni
@@ -623,6 +542,7 @@ public class RTABMapActivity extends Activity implements OnClickListener {
}; };
fileList = path.list(filter); fileList = path.list(filter);
Arrays.sort(fileList);
} }
else { else {
fileList = new String[0]; fileList = new String[0];
@@ -637,21 +557,62 @@ public class RTABMapActivity extends Activity implements OnClickListener {
{ {
item.setChecked(!item.isChecked()); item.setChecked(!item.isChecked());
mItemSave.setEnabled(item.isChecked()); mItemSave.setEnabled(item.isChecked());
mItemExport.setEnabled(item.isChecked()); mItemExport.setEnabled(item.isChecked() && !mItemDataRecorderMode.isChecked());
mItemOpen.setEnabled(item.isChecked()); mItemOpen.setEnabled(item.isChecked() && !mItemDataRecorderMode.isChecked());
mItemPostProcessing.setEnabled(item.isChecked()); mItemPostProcessing.setEnabled(item.isChecked() && !mItemDataRecorderMode.isChecked());
// mItemSave.setEnabled(item.isChecked() && !mWorkingDirectory.isEmpty()); mItemDataRecorderMode.setEnabled(item.isChecked());
if(item.isChecked()) if(item.isChecked())
{ {
RTABMapLib.setPausedMapping(true); RTABMapLib.setPausedMapping(true);
((TextView)findViewById(R.id.status)).setText("Paused"); ((TextView)findViewById(R.id.status)).setText("Paused");
if(mPauseFirstTime && !mOnPause)
{
mPauseFirstTime = false;
mToast.makeText(getActivity(), String.format("Tip: Try \"Post-Processing...\" to optimize even more the map!"), mToast.LENGTH_LONG).show();
}
mMapIsEmpty = false;
} }
else else
{ {
RTABMapLib.setPausedMapping(false); RTABMapLib.setPausedMapping(false);
((TextView)findViewById(R.id.status)).setText(mItemLocalizationMode.isChecked()?"Localization":"Mapping"); ((TextView)findViewById(R.id.status)).setText(mItemLocalizationMode.isChecked()?"Localization":mItemDataRecorderMode.isChecked()?"Recording":"Mapping");
if(mItemDataRecorderMode.isChecked())
{
mToast.makeText(getActivity(), String.format("Data Recorder Mode: no map is created, only raw data is recorded."), mToast.LENGTH_LONG).show();
}
else if(!mMapIsEmpty)
{
mToast.makeText(getActivity(), String.format("On resume, a new map is created. Tip: Try relocalizing in the previous area."), mToast.LENGTH_LONG).show();
}
} }
} }
else if (itemId == R.id.post_processing_standard)
{
mProgressDialog.setTitle("Post-Processing");
mProgressDialog.setMessage(String.format("Please wait while optimizing..."));
mProgressDialog.show();
Thread workingThread = new Thread(new Runnable() {
public void run() {
final int loopDetected = RTABMapLib.postProcessing(-1);
runOnUiThread(new Runnable() {
public void run() {
if(loopDetected >= 0)
{
mTotalLoopClosures+=loopDetected;
mProgressDialog.setMessage(String.format("Optimization done! Increasing visual appeal..."));
}
else if(loopDetected < 0)
{
mToast.makeText(getActivity(), String.format("Optimization failed!"), mToast.LENGTH_SHORT).show();
}
}
});
}
});
workingThread.start();
}
else if (itemId == R.id.detect_more_loop_closures) else if (itemId == R.id.detect_more_loop_closures)
{ {
mProgressDialog.setTitle("Post-Processing"); mProgressDialog.setTitle("Post-Processing");
@@ -679,6 +640,32 @@ public class RTABMapActivity extends Activity implements OnClickListener {
}); });
workingThread.start(); workingThread.start();
} }
else if (itemId == R.id.icp_refining)
{
mProgressDialog.setTitle("Post-Processing");
mProgressDialog.setMessage(String.format("Please wait while refining links..."));
mProgressDialog.show();
Thread workingThread = new Thread(new Runnable() {
public void run() {
final int linksRefined = RTABMapLib.postProcessing(3);
runOnUiThread(new Runnable() {
public void run() {
mProgressDialog.dismiss();
if(linksRefined >= 0)
{
mToast.makeText(getActivity(), String.format("Refining done! %d link(s) refined.", linksRefined), mToast.LENGTH_SHORT).show();
}
else if(linksRefined < 0)
{
mToast.makeText(getActivity(), String.format("Refining failed!"), mToast.LENGTH_SHORT).show();
}
}
});
}
});
workingThread.start();
}
else if (itemId == R.id.global_graph_optimization) else if (itemId == R.id.global_graph_optimization)
{ {
mProgressDialog.setTitle("Post-Processing"); mProgressDialog.setTitle("Post-Processing");
@@ -705,6 +692,34 @@ public class RTABMapActivity extends Activity implements OnClickListener {
}); });
workingThread.start(); workingThread.start();
} }
else if (itemId == R.id.polygons_filtering)
{
mProgressDialog.setTitle("Post-Processing");
mProgressDialog.setMessage(String.format("Noise filtering..."));
mProgressDialog.show();
RTABMapLib.postProcessing(4);
}
else if (itemId == R.id.gain_compensation_fast)
{
mProgressDialog.setTitle("Post-Processing");
mProgressDialog.setMessage(String.format("Fast gain compensation..."));
mProgressDialog.show();
RTABMapLib.postProcessing(5);
}
else if (itemId == R.id.gain_compensation_full)
{
mProgressDialog.setTitle("Post-Processing");
mProgressDialog.setMessage(String.format("Full gain compensation..."));
mProgressDialog.show();
RTABMapLib.postProcessing(6);
}
else if (itemId == R.id.bilateral_filtering)
{
mProgressDialog.setTitle("Post-Processing");
mProgressDialog.setMessage(String.format("Mesh smoothing..."));
mProgressDialog.show();
RTABMapLib.postProcessing(7);
}
else if (itemId == R.id.sba) else if (itemId == R.id.sba)
{ {
mProgressDialog.setTitle("Post-Processing"); mProgressDialog.setTitle("Post-Processing");
@@ -743,10 +758,12 @@ public class RTABMapActivity extends Activity implements OnClickListener {
mLayoutDebug.setVisibility(LinearLayout.VISIBLE); mLayoutDebug.setVisibility(LinearLayout.VISIBLE);
} }
} }
else if(itemId == R.id.mesh_rendering) else if(itemId == R.id.mesh || itemId == R.id.texture_mesh || itemId == R.id.point_cloud)
{ {
item.setChecked(!item.isChecked()); item.setChecked(true);
RTABMapLib.setMeshRendering(item.isChecked()); RTABMapLib.setMeshRendering(
mItemRenderingMesh.isChecked() || mItemRenderingTextureMesh.isChecked(),
mItemRenderingTextureMesh.isChecked());
} }
else if(itemId == R.id.map_shown) else if(itemId == R.id.map_shown)
{ {
@@ -778,11 +795,25 @@ public class RTABMapActivity extends Activity implements OnClickListener {
item.setChecked(!item.isChecked()); item.setChecked(!item.isChecked());
RTABMapLib.setNodesFiltering(item.isChecked()); RTABMapLib.setNodesFiltering(item.isChecked());
} }
else if(itemId == R.id.drift_correction)
{
item.setChecked(!item.isChecked());
RTABMapLib.setDriftCorrection(item.isChecked());
if(item.isChecked())
{
mToast.makeText(getActivity(), String.format("Tip: With drift correction is enabled, move slowly to get better results."), mToast.LENGTH_LONG).show();
}
}
else if(itemId == R.id.graph_visible) else if(itemId == R.id.graph_visible)
{ {
item.setChecked(!item.isChecked()); item.setChecked(!item.isChecked());
RTABMapLib.setGraphVisible(item.isChecked()); RTABMapLib.setGraphVisible(item.isChecked());
} }
else if(itemId == R.id.grid_visible)
{
item.setChecked(!item.isChecked());
RTABMapLib.setGridVisible(item.isChecked());
}
else if(itemId == R.id.auto_exposure) else if(itemId == R.id.auto_exposure)
{ {
item.setChecked(!item.isChecked()); item.setChecked(!item.isChecked());
@@ -797,6 +828,11 @@ public class RTABMapActivity extends Activity implements OnClickListener {
item.setChecked(!item.isChecked()); item.setChecked(!item.isChecked());
RTABMapLib.setFullResolution(item.isChecked()); RTABMapLib.setFullResolution(item.isChecked());
} }
else if(itemId == R.id.append)
{
item.setChecked(!item.isChecked());
RTABMapLib.setAppendMode(item.isChecked());
}
else if(itemId == R.id.max_depth) else if(itemId == R.id.max_depth)
{ {
// get double // get double
@@ -816,6 +852,25 @@ public class RTABMapActivity extends Activity implements OnClickListener {
}); });
builder.show(); builder.show();
} }
else if(itemId == R.id.mesh_decimation)
{
// get double
AlertDialog.Builder builder = new AlertDialog.Builder(this);
builder.setTitle("Mesh Decimation");
final String[] values = {"Disabled", "Medium", "High"};
builder.setSingleChoiceItems(values, mMeshDecimationIndex, new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
dialog.dismiss();
if(which >=0 && which <= 2)
{
mMeshDecimationIndex = which;
RTABMapLib.setMeshDecimation(which);
}
}
});
builder.show();
}
else if(itemId == R.id.mesh_angle_tolerance) else if(itemId == R.id.mesh_angle_tolerance)
{ {
// get double // get double
@@ -866,7 +921,7 @@ public class RTABMapActivity extends Activity implements OnClickListener {
if(which >=0 && which < mUpdateRateValues.length) if(which >=0 && which < mUpdateRateValues.length)
{ {
mParamUpdateRateHzIndex = which; mParamUpdateRateHzIndex = which;
if(RTABMapLib.setMappingParameter("Rtabmap/DetectionRate", mUpdateRateValues[which]) != 0) if(RTABMapLib.setMappingParameter("Rtabmap/DetectionRate", which == mUpdateRateValues.length-1?"0":mUpdateRateValues[which]) != 0)
{ {
mToast.makeText(getActivity(), "Failed to set parameter \"Rtabmap/DetectionRate\"!", mToast.LENGTH_LONG).show(); mToast.makeText(getActivity(), "Failed to set parameter \"Rtabmap/DetectionRate\"!", mToast.LENGTH_LONG).show();
} }
@@ -961,83 +1016,165 @@ public class RTABMapActivity extends Activity implements OnClickListener {
} }
else if (itemId == R.id.save) else if (itemId == R.id.save)
{ {
if(mOpenedDatabasePath.isEmpty()) AlertDialog.Builder builder = new AlertDialog.Builder(this);
{ builder.setTitle("RTAB-Map Database Name (*.db):");
AlertDialog.Builder builder = new AlertDialog.Builder(this); final EditText input = new EditText(this);
builder.setTitle("RTAB-Map Database Name (*.db):"); input.setInputType(InputType.TYPE_CLASS_TEXT);
final EditText input = new EditText(this); if(mOpenedDatabasePath.isEmpty())
input.setInputType(InputType.TYPE_CLASS_TEXT); {
builder.setView(input); String timeStamp = new SimpleDateFormat("yyMMdd-hhmmss").format(new Date());
builder.setPositiveButton("OK", new DialogInterface.OnClickListener() { input.setText(timeStamp);
@Override }
public void onClick(DialogInterface dialog, int which) else
{
File f = new File(mOpenedDatabasePath);
String name = f.getName();
input.setText(name.substring(0,name.lastIndexOf(".")));
}
input.setSelectAllOnFocus(true);
input.selectAll();
builder.setView(input);
builder.setPositiveButton("OK", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which)
{
final String fileName = input.getText().toString();
dialog.dismiss();
if(!fileName.isEmpty())
{ {
final String fileName = input.getText().toString(); File newFile = new File(mWorkingDirectory + fileName + ".db");
dialog.dismiss(); if(newFile.exists())
if(!fileName.isEmpty())
{ {
File newFile = new File(mWorkingDirectory + fileName + ".db"); new AlertDialog.Builder(getActivity())
if(newFile.exists()) .setTitle("File Already Exists")
{ .setMessage("Do you want to overwrite the existing file?")
new AlertDialog.Builder(getActivity()) .setPositiveButton("Yes", new DialogInterface.OnClickListener() {
.setTitle("File Already Exists") public void onClick(DialogInterface dialog, int which) {
.setMessage("Do you want to overwrite the existing file?")
.setPositiveButton("Yes", new DialogInterface.OnClickListener() { final String newDatabasePath = mWorkingDirectory + fileName + ".db";
public void onClick(DialogInterface dialog, int which) { mProgressDialog.setTitle("Saving");
mNewDatabasePath = mWorkingDirectory + fileName + ".db"; if(mOpenedDatabasePath.equals(newDatabasePath))
{
mProgressDialog.setTitle("Saving"); mProgressDialog.setMessage(String.format("Please wait while updating \"%s\"...", newDatabasePath));
mProgressDialog.setMessage(String.format("Please wait while saving \"%s\"...", mNewDatabasePath)); }
mProgressDialog.show(); else
{
RTABMapLib.save(); // send save event mProgressDialog.setMessage(String.format("Please wait while saving \"%s\"...", newDatabasePath));
//disable gui actions }
mItemSave.setEnabled(false); mProgressDialog.show();
mItemOpen.setEnabled(false);
mItemPostProcessing.setEnabled(false); Thread saveThread = new Thread(new Runnable() {
mItemExport.setEnabled(false); public void run() {
} RTABMapLib.save(newDatabasePath); // save
}) runOnUiThread(new Runnable() {
.setNegativeButton("No", new DialogInterface.OnClickListener() { public void run() {
public void onClick(DialogInterface dialog, int which) { if(mOpenedDatabasePath.equals(newDatabasePath))
dialog.dismiss(); {
} mToast.makeText(getActivity(), String.format("Database \"%s\" updated.", newDatabasePath), mToast.LENGTH_LONG).show();
}) }
.show(); else
} {
else mToast.makeText(getActivity(), String.format("Database saved to \"%s\".", newDatabasePath), mToast.LENGTH_LONG).show();
{
mNewDatabasePath = mWorkingDirectory + fileName + ".db"; Intent intent = new Intent(getActivity(), RTABMapActivity.class);
// use System.currentTimeMillis() to have a unique ID for the pending intent
mProgressDialog.setTitle("Saving"); PendingIntent pIntent = PendingIntent.getActivity(getActivity(), (int) System.currentTimeMillis(), intent, 0);
mProgressDialog.setMessage(String.format("Please wait while saving \"%s\"...", mNewDatabasePath));
mProgressDialog.show(); // build notification
// the addAction re-use the same intent to keep the example short
RTABMapLib.save(); // send save event Notification n = new Notification.Builder(getActivity())
//disable gui actions .setContentTitle(getString(R.string.app_name))
mItemSave.setEnabled(false); .setContentText(newDatabasePath + " saved!")
mItemOpen.setEnabled(false); .setSmallIcon(R.drawable.ic_launcher)
mItemPostProcessing.setEnabled(false); .setContentIntent(pIntent)
mItemExport.setEnabled(false); .setAutoCancel(true).build();
}
NotificationManager notificationManager =
(NotificationManager) getSystemService(NOTIFICATION_SERVICE);
notificationManager.notify(0, n);
}
if(!mItemDataRecorderMode.isChecked())
{
mOpenedDatabasePath = newDatabasePath;
}
mProgressDialog.dismiss();
}
});
}
});
saveThread.start();
}
})
.setNegativeButton("No", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int which) {
dialog.dismiss();
}
})
.show();
}
else
{
final String newDatabasePath = mWorkingDirectory + fileName + ".db";
mProgressDialog.setTitle("Saving");
if(mOpenedDatabasePath.equals(newDatabasePath))
{
mProgressDialog.setMessage(String.format("Please wait while updating \"%s\"...", mOpenedDatabasePath));
}
else
{
mProgressDialog.setMessage(String.format("Please wait while saving \"%s\"...", newDatabasePath));
}
mProgressDialog.show();
Thread saveThread = new Thread(new Runnable() {
public void run() {
RTABMapLib.save(newDatabasePath); // save
runOnUiThread(new Runnable() {
public void run() {
if(mOpenedDatabasePath.equals(newDatabasePath))
{
mToast.makeText(getActivity(), String.format("Database \"%s\" updated.", newDatabasePath), mToast.LENGTH_LONG).show();
}
else
{
mToast.makeText(getActivity(), String.format("Database saved to \"%s\".", newDatabasePath), mToast.LENGTH_LONG).show();
Intent intent = new Intent(getActivity(), RTABMapActivity.class);
// use System.currentTimeMillis() to have a unique ID for the pending intent
PendingIntent pIntent = PendingIntent.getActivity(getActivity(), (int) System.currentTimeMillis(), intent, 0);
// build notification
// the addAction re-use the same intent to keep the example short
Notification n = new Notification.Builder(getActivity())
.setContentTitle(getString(R.string.app_name))
.setContentText(newDatabasePath + " saved!")
.setSmallIcon(R.drawable.ic_launcher)
.setContentIntent(pIntent)
.setAutoCancel(true).build();
NotificationManager notificationManager =
(NotificationManager) getSystemService(NOTIFICATION_SERVICE);
notificationManager.notify(0, n);
}
if(!mItemDataRecorderMode.isChecked())
{
mOpenedDatabasePath = newDatabasePath;
}
mProgressDialog.dismiss();
}
});
}
});
saveThread.start();
} }
} }
}); }
builder.show(); });
} builder.show();
else
{
mProgressDialog.setTitle("Saving");
mProgressDialog.setMessage(String.format("Please wait while updating \"%s\"...", mOpenedDatabasePath));
mProgressDialog.show();
RTABMapLib.save(); // send save event
//disable gui actions
mItemSave.setEnabled(false);
mItemOpen.setEnabled(false);
mItemPostProcessing.setEnabled(false);
mItemExport.setEnabled(false);
}
} }
else if(itemId == R.id.reset) else if(itemId == R.id.reset)
{ {
@@ -1062,8 +1199,62 @@ public class RTABMapActivity extends Activity implements OnClickListener {
else else
{ {
mOpenedDatabasePath = ""; mOpenedDatabasePath = "";
RTABMapLib.openDatabase(mTempDatabasePath); RTABMapLib.openEmptyDatabase();
} }
mMapIsEmpty = true;
}
else if(itemId == R.id.data_recorder)
{
final boolean dataRecorderOldState = item.isChecked();
new AlertDialog.Builder(getActivity())
.setTitle("Data Recorder Mode")
.setMessage("Changing from/to data recorder mode will close the current session. Do you want to continue?")
.setPositiveButton("Yes", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int which) {
// reset
((TextView)findViewById(R.id.points)).setText(String.valueOf(0));
((TextView)findViewById(R.id.polygons)).setText(String.valueOf(0));
((TextView)findViewById(R.id.nodes)).setText(String.valueOf(0));
((TextView)findViewById(R.id.words)).setText(String.valueOf(0));
((TextView)findViewById(R.id.memory)).setText(String.valueOf(Debug.getNativeHeapAllocatedSize()/(1024*1024)));
((TextView)findViewById(R.id.db_size)).setText(String.valueOf(0));
((TextView)findViewById(R.id.inliers)).setText(String.valueOf(0));
((TextView)findViewById(R.id.features)).setText(String.valueOf(0));
((TextView)findViewById(R.id.update_time)).setText(String.valueOf(0));
((TextView)findViewById(R.id.hypothesis)).setText(String.valueOf(0));
((TextView)findViewById(R.id.fps)).setText(String.valueOf(0));
mTotalLoopClosures = 0;
((TextView)findViewById(R.id.total_loop)).setText(String.valueOf(mTotalLoopClosures));
mItemDataRecorderMode.setChecked(!dataRecorderOldState);
RTABMapLib.setDataRecorderMode(mItemDataRecorderMode.isChecked());
mOpenedDatabasePath = "";
RTABMapLib.openEmptyDatabase();
mItemOpen.setEnabled(!mItemDataRecorderMode.isChecked() && mItemPause.isChecked());
mItemPostProcessing.setEnabled(!mItemDataRecorderMode.isChecked() && mItemPause.isChecked());
mItemExport.setEnabled(!mItemDataRecorderMode.isChecked() && mItemPause.isChecked());
mItemLocalizationMode.setEnabled(!mItemDataRecorderMode.isChecked());
mItemAppendMode.setEnabled(!mItemDataRecorderMode.isChecked());
if(mItemDataRecorderMode.isChecked())
{
mToast.makeText(getActivity(), String.format("Data recorder mode activated! Tip: You can increase data update rate in Parameters menu under Mapping options."), mToast.LENGTH_LONG).show();
}
else
{
mToast.makeText(getActivity(), String.format("Data recorder mode deactivated!"), mToast.LENGTH_LONG).show();
}
}
})
.setNegativeButton("No", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int which) {
dialog.dismiss();
}
})
.show();
} }
else if(itemId == R.id.export_obj || itemId == R.id.export_ply) else if(itemId == R.id.export_obj || itemId == R.id.export_ply)
{ {
@@ -1077,6 +1268,19 @@ public class RTABMapActivity extends Activity implements OnClickListener {
final EditText input = new EditText(this); final EditText input = new EditText(this);
input.setInputType(InputType.TYPE_CLASS_TEXT); input.setInputType(InputType.TYPE_CLASS_TEXT);
builder.setView(input); builder.setView(input);
if(mOpenedDatabasePath.isEmpty())
{
String timeStamp = new SimpleDateFormat("yyMMdd-hhmmss").format(new Date());
input.setText(timeStamp);
}
else
{
File f = new File(mOpenedDatabasePath);
String name = f.getName();
input.setText(name.substring(0,name.lastIndexOf(".")));
}
input.setSelectAllOnFocus(true);
input.selectAll();
builder.setPositiveButton("OK", new DialogInterface.OnClickListener() { builder.setPositiveButton("OK", new DialogInterface.OnClickListener() {
@Override @Override
public void onClick(DialogInterface dialog, int which) public void onClick(DialogInterface dialog, int which)
@@ -1130,6 +1334,24 @@ public class RTABMapActivity extends Activity implements OnClickListener {
{ {
mToast.makeText(getActivity(), String.format("Mesh \"%s\" successfully exported!", path), mToast.LENGTH_LONG).show(); mToast.makeText(getActivity(), String.format("Mesh \"%s\" successfully exported!", path), mToast.LENGTH_LONG).show();
} }
Intent intent = new Intent(getActivity(), RTABMapActivity.class);
// use System.currentTimeMillis() to have a unique ID for the pending intent
PendingIntent pIntent = PendingIntent.getActivity(getActivity(), (int) System.currentTimeMillis(), intent, 0);
// build notification
// the addAction re-use the same intent to keep the example short
Notification n = new Notification.Builder(getActivity())
.setContentTitle(getString(R.string.app_name))
.setContentText(path + " exported!")
.setSmallIcon(R.drawable.ic_launcher)
.setContentIntent(pIntent)
.setAutoCancel(true).build();
NotificationManager notificationManager =
(NotificationManager) getSystemService(NOTIFICATION_SERVICE);
notificationManager.notify(0, n);
} }
else else
{ {
@@ -1173,6 +1395,25 @@ public class RTABMapActivity extends Activity implements OnClickListener {
{ {
mToast.makeText(getActivity(), String.format("Mesh \"%s\" successfully exported!", path), mToast.LENGTH_LONG).show(); mToast.makeText(getActivity(), String.format("Mesh \"%s\" successfully exported!", path), mToast.LENGTH_LONG).show();
} }
Intent intent = new Intent(getActivity(), RTABMapActivity.class);
// use System.currentTimeMillis() to have a unique ID for the pending intent
PendingIntent pIntent = PendingIntent.getActivity(getActivity(), (int) System.currentTimeMillis(), intent, 0);
// build notification
// the addAction re-use the same intent to keep the example short
Notification n = new Notification.Builder(getActivity())
.setContentTitle(getString(R.string.app_name))
.setContentText(path + " exported!")
.setSmallIcon(R.drawable.ic_launcher)
.setContentIntent(pIntent)
.setAutoCancel(true).build();
NotificationManager notificationManager =
(NotificationManager) getSystemService(NOTIFICATION_SERVICE);
notificationManager.notify(0, n);
} }
else else
{ {
@@ -1196,9 +1437,16 @@ public class RTABMapActivity extends Activity implements OnClickListener {
final String[] files = loadFileList(mWorkingDirectory); final String[] files = loadFileList(mWorkingDirectory);
if(files.length > 0) if(files.length > 0)
{ {
String[] filesWithSize = new String[files.length];
for(int i = 0; i<filesWithSize.length; ++i)
{
File filePath = new File(mWorkingDirectory+files[i]);
long mb = filePath.length()/(1024*1024);
filesWithSize[i] = files[i] + " ("+mb+" MB)";
}
AlertDialog.Builder builder = new AlertDialog.Builder(this); AlertDialog.Builder builder = new AlertDialog.Builder(this);
builder.setTitle("Choose your file"); builder.setTitle("Choose your file");
builder.setItems(files, new DialogInterface.OnClickListener() { builder.setItems(filesWithSize, new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int which) { public void onClick(DialogInterface dialog, int which) {
mOpenedDatabasePath = mWorkingDirectory + files[which]; mOpenedDatabasePath = mWorkingDirectory + files[which];
@@ -1211,12 +1459,6 @@ public class RTABMapActivity extends Activity implements OnClickListener {
RTABMapLib.openDatabase(mOpenedDatabasePath); RTABMapLib.openDatabase(mOpenedDatabasePath);
RTABMapLib.setCamera(1); RTABMapLib.setCamera(1);
File extStore = new File(mTempDatabasePath);
if(extStore.exists())
{
extStore.delete();
}
} }
}); });
builder.show(); builder.show();

View File

@@ -25,6 +25,7 @@ public class RTABMapLib
// The activity object is used for checking if the API version is outdated. // The activity object is used for checking if the API version is outdated.
public static native void onCreate(RTABMapActivity activity); public static native void onCreate(RTABMapActivity activity);
public static native void openEmptyDatabase();
public static native void openDatabase(String databasePath); public static native void openDatabase(String databasePath);
/* /*
@@ -58,21 +59,26 @@ public class RTABMapLib
public static native void setPausedMapping(boolean paused); public static native void setPausedMapping(boolean paused);
public static native void setMapCloudShown(boolean shown); public static native void setMapCloudShown(boolean shown);
public static native void setOdomCloudShown(boolean shown); public static native void setOdomCloudShown(boolean shown);
public static native void setMeshRendering(boolean enabled); public static native void setMeshRendering(boolean enabled, boolean withTexture);
public static native void setLocalizationMode(boolean enabled); public static native void setLocalizationMode(boolean enabled);
public static native void setTrajectoryMode(boolean enabled); public static native void setTrajectoryMode(boolean enabled);
public static native void setGraphOptimization(boolean enabled); public static native void setGraphOptimization(boolean enabled);
public static native void setNodesFiltering(boolean enabled); public static native void setNodesFiltering(boolean enabled);
public static native void setDriftCorrection(boolean enabled);
public static native void setGraphVisible(boolean visible); public static native void setGraphVisible(boolean visible);
public static native void setGridVisible(boolean visible);
public static native void setAutoExposure(boolean enabled); public static native void setAutoExposure(boolean enabled);
public static native void setFullResolution(boolean enabled); public static native void setFullResolution(boolean enabled);
public static native void setAppendMode(boolean enabled);
public static native void setDataRecorderMode(boolean enabled);
public static native void setMaxCloudDepth(float value); public static native void setMaxCloudDepth(float value);
public static native void setMeshDecimation(int value);
public static native void setMeshAngleTolerance(float value); public static native void setMeshAngleTolerance(float value);
public static native void setMeshTriangleSize(int value); public static native void setMeshTriangleSize(int value);
public static native int setMappingParameter(String key, String value); public static native int setMappingParameter(String key, String value);
public static native void resetMapping(); public static native void resetMapping();
public static native void save(); public static native void save(String outputDatabasePath);
public static native boolean exportMesh(String filePath); public static native boolean exportMesh(String filePath);
public static native int postProcessing(int approach); public static native int postProcessing(int approach);

View File

@@ -137,11 +137,25 @@ IF((APPLE AND BUILD_AS_BUNDLE) OR WIN32)
# Install needed Qt plugins by copying directories from the qt installation # Install needed Qt plugins by copying directories from the qt installation
# One can cull what gets copied by using 'REGEX "..." EXCLUDE' # One can cull what gets copied by using 'REGEX "..." EXCLUDE'
# Exclude debug libraries # Exclude debug libraries
INSTALL(DIRECTORY "${QT_PLUGINS_DIR}/imageformats" IF(QT_PLUGINS_DIR)
INSTALL(DIRECTORY "${QT_PLUGINS_DIR}/imageformats"
DESTINATION ${plugin_dest_dir}/plugins DESTINATION ${plugin_dest_dir}/plugins
COMPONENT runtime COMPONENT runtime
REGEX ".*d4.dll" EXCLUDE REGEX ".*d4.dll" EXCLUDE
REGEX ".*d4.a" EXCLUDE) REGEX ".*d4.a" EXCLUDE)
ELSE()
#Qt5
foreach(plugin ${Qt5Gui_PLUGINS})
get_target_property(plugin_loc ${plugin} LOCATION)
get_filename_component(plugin_dir ${plugin_loc} DIRECTORY)
string(REPLACE "plugins" ";" loc_list ${plugin_dir})
list(GET loc_list 1 plugin_type)
#MESSAGE(STATUS "Qt5 plugin \"${plugin_loc}\" installed in \"${plugin_dest_dir}/plugins${plugin_type}\"")
INSTALL(FILES ${plugin_loc}
DESTINATION ${plugin_dest_dir}/plugins${plugin_type}
COMPONENT runtime)
endforeach()
ENDIF()
# install a qt.conf file # install a qt.conf file
# this inserts some cmake code into the install script to write the file # this inserts some cmake code into the install script to write the file

View File

@@ -1,5 +1,5 @@
/* /*
Copyright (c) 2010-2014, Mathieu Labbe - IntRoLab - Universite de Sherbrooke Copyright (c) 2010-2016, Mathieu Labbe - IntRoLab - Universite de Sherbrooke
All rights reserved. All rights reserved.
Redistribution and use in source and binary forms, with or without Redistribution and use in source and binary forms, with or without

View File

@@ -1,5 +1,5 @@
/* /*
Copyright (c) 2010-2014, Mathieu Labbe - IntRoLab - Universite de Sherbrooke Copyright (c) 2010-2016, Mathieu Labbe - IntRoLab - Universite de Sherbrooke
All rights reserved. All rights reserved.
Redistribution and use in source and binary forms, with or without Redistribution and use in source and binary forms, with or without
@@ -47,6 +47,8 @@ int main(int argc, char* argv[])
/* Create tasks */ /* Create tasks */
QApplication * app = new QApplication(argc, argv); QApplication * app = new QApplication(argc, argv);
ParametersMap parameters = Parameters::parseArguments(argc, argv, true);
MainWindow * mainWindow = new MainWindow(); MainWindow * mainWindow = new MainWindow();
app->installEventFilter(mainWindow); // to catch FileOpen events. app->installEventFilter(mainWindow); // to catch FileOpen events.
@@ -82,7 +84,11 @@ int main(int argc, char* argv[])
if(!database.empty()) if(!database.empty())
{ {
QMetaObject::invokeMethod(mainWindow, "openDatabase", Qt::QueuedConnection, Q_ARG(QString, QString(database.c_str()))); mainWindow->openDatabase(database.c_str());
}
if(parameters.size())
{
mainWindow->updateParameters(parameters);
} }
// Now wait for application to finish // Now wait for application to finish

View File

@@ -13,9 +13,9 @@ IF (DC1394_INCLUDE_DIRS AND DC1394_LIBRARIES)
SET(DC1394_FOUND TRUE) SET(DC1394_FOUND TRUE)
#On Mac OS X #On Mac OS X
if(CMAKE_SYSTEM_NAME MATCHES "Darwin") #if(CMAKE_SYSTEM_NAME MATCHES "Darwin")
set(DC1394_LIBRARIES ${DC1394_LIBRARIES} "-framework CoreServices") # set(DC1394_LIBRARIES ${DC1394_LIBRARIES} "-framework CoreServices")
endif(CMAKE_SYSTEM_NAME MATCHES "Darwin") #endif(CMAKE_SYSTEM_NAME MATCHES "Darwin")
ENDIF (DC1394_INCLUDE_DIRS AND DC1394_LIBRARIES) ENDIF (DC1394_INCLUDE_DIRS AND DC1394_LIBRARIES)

View File

@@ -18,8 +18,7 @@ FIND_PATH(G2O_INCLUDE_DIR g2o/core/base_vertex.h
PATHS "C:\\Program Files\\g2o\\include") PATHS "C:\\Program Files\\g2o\\include")
# Macro to unify finding both the debug and release versions of the # Macro to unify finding both the debug and release versions of the
# libraries; this is adapted from the OpenSceneGraph FIND_LIBRARY # libraries; this is adapted from the rtabmap config
# macro.
MACRO(FIND_G2O_LIBRARY MYLIBRARY MYLIBRARYNAME) MACRO(FIND_G2O_LIBRARY MYLIBRARY MYLIBRARYNAME)
@@ -31,11 +30,14 @@ MACRO(FIND_G2O_LIBRARY MYLIBRARY MYLIBRARYNAME)
NAMES "g2o_${MYLIBRARYNAME}" NAMES "g2o_${MYLIBRARYNAME}"
PATHS "C:\\Program Files\\g2o\\lib") PATHS "C:\\Program Files\\g2o\\lib")
IF(NOT ${MYLIBRARY}_DEBUG) IF(${MYLIBRARY}_DEBUG AND ${MYLIBRARY})
IF(MYLIBRARY) SET(${MYLIBRARY}
SET(${MYLIBRARY}_DEBUG ${MYLIBRARY}) debug ${${MYLIBRARY}_DEBUG}
ENDIF(MYLIBRARY) optimized ${${MYLIBRARY}}
ENDIF( NOT ${MYLIBRARY}_DEBUG) )
ELSEIF(${MYLIBRARY}_DEBUG)
SET(${MYLIBRARY} ${${MYLIBRARY}_DEBUG})
ENDIF()
ENDMACRO(FIND_G2O_LIBRARY LIBRARY LIBRARYNAME) ENDMACRO(FIND_G2O_LIBRARY LIBRARY LIBRARYNAME)

View File

@@ -0,0 +1,34 @@
# - Find librealsense (https://github.com/IntelRealSense/librealsense)
#
# RealSense_ROOT_DIR environment variable can be set to find the library.
#
# It sets the following variables:
# RealSense_FOUND - Set to false, or undefined, if RealSense isn't found.
# RealSense_INCLUDE_DIRS - The RealSense include directory.
# RealSense_LIBRARIES - The RealSense library to link against.
#RealSense library
find_path(RealSense_INCLUDE_DIRS NAMES librealsense/rs.hpp PATHS $ENV{RealSense_ROOT_DIR}/include)
if(CMAKE_CL_64)
find_library(RealSense_LIBRARY NAMES realsense PATHS $ENV{RealSense_ROOT_DIR}/lib $ENV{RealSense_ROOT_DIR}/bin $ENV{RealSense_ROOT_DIR}/bin/x64)
else()
find_library(RealSense_LIBRARY NAMES realsense PATHS $ENV{RealSense_ROOT_DIR}/lib $ENV{RealSense_ROOT_DIR}/bin $ENV{RealSense_ROOT_DIR}/bin/Win32)
endif()
IF (RealSense_INCLUDE_DIRS AND RealSense_LIBRARY)
SET(RealSense_FOUND TRUE)
ENDIF (RealSense_INCLUDE_DIRS AND RealSense_LIBRARY)
IF (RealSense_FOUND)
# show which RealSense was found only if not quiet
SET(RealSense_LIBRARIES ${RealSense_LIBRARY})
IF (NOT RealSense_FIND_QUIETLY)
MESSAGE(STATUS "Found RealSense: ${RealSense_LIBRARIES}")
ENDIF (NOT RealSense_FIND_QUIETLY)
ELSE (RealSense_FOUND)
# fatal error if RealSense is required but not found
IF (RealSense_FIND_REQUIRED)
MESSAGE(FATAL_ERROR "Could not find RealSense (librealsense)")
ENDIF (RealSense_FIND_REQUIRED)
ENDIF (RealSense_FOUND)

View File

@@ -9,12 +9,13 @@
FIND_PATH(Tango_INCLUDE_DIR tango_client_api.h) FIND_PATH(Tango_INCLUDE_DIR tango_client_api.h)
FIND_LIBRARY(Tango_LIBRARY NAMES tango_client_api) FIND_LIBRARY(Tango_LIBRARY NAMES tango_client_api)
FIND_LIBRARY(Tango_support_LIBRARY NAMES tango_support_api)
IF (Tango_INCLUDE_DIR AND Tango_LIBRARY) IF (Tango_INCLUDE_DIR AND Tango_LIBRARY AND Tango_support_LIBRARY)
SET(Tango_FOUND TRUE) SET(Tango_FOUND TRUE)
SET(Tango_INCLUDE_DIRS ${Tango_INCLUDE_DIR}) SET(Tango_INCLUDE_DIRS ${Tango_INCLUDE_DIR})
SET(Tango_LIBRARIES ${Tango_LIBRARY}) SET(Tango_LIBRARIES ${Tango_LIBRARY} ${Tango_support_LIBRARY})
ENDIF (Tango_INCLUDE_DIR AND Tango_LIBRARY) ENDIF (Tango_INCLUDE_DIR AND Tango_LIBRARY AND Tango_support_LIBRARY)
IF (Tango_FOUND) IF (Tango_FOUND)
# show which Tango was found only if not quiet # show which Tango was found only if not quiet
@@ -24,7 +25,7 @@ IF (Tango_FOUND)
ELSE (Tango_FOUND) ELSE (Tango_FOUND)
# fatal error if Tango is required but not found # fatal error if Tango is required but not found
IF (Tango_FIND_REQUIRED) IF (Tango_FIND_REQUIRED)
MESSAGE(FATAL_ERROR "Could not find Tango") MESSAGE(FATAL_ERROR "Could not find Tango (client and/or support libraries)")
ENDIF (Tango_FIND_REQUIRED) ENDIF (Tango_FIND_REQUIRED)
ENDIF (Tango_FOUND) ENDIF (Tango_FOUND)

View File

@@ -1,5 +1,5 @@
/* /*
Copyright (c) 2010-2014, Mathieu Labbe - IntRoLab - Universite de Sherbrooke Copyright (c) 2010-2016, Mathieu Labbe - IntRoLab - Universite de Sherbrooke
All rights reserved. All rights reserved.
Redistribution and use in source and binary forms, with or without Redistribution and use in source and binary forms, with or without

View File

@@ -1,5 +1,5 @@
/* /*
Copyright (c) 2010-2014, Mathieu Labbe - IntRoLab - Universite de Sherbrooke Copyright (c) 2010-2016, Mathieu Labbe - IntRoLab - Universite de Sherbrooke
All rights reserved. All rights reserved.
Redistribution and use in source and binary forms, with or without Redistribution and use in source and binary forms, with or without
@@ -56,6 +56,7 @@ public:
virtual bool init(const std::string & calibrationFolder = ".", const std::string & cameraName = "") = 0; virtual bool init(const std::string & calibrationFolder = ".", const std::string & cameraName = "") = 0;
virtual bool isCalibrated() const = 0; virtual bool isCalibrated() const = 0;
virtual std::string getSerial() const = 0; virtual std::string getSerial() const = 0;
virtual bool odomProvided() const { return false; }
//getters //getters
float getImageRate() const {return _imageRate;} float getImageRate() const {return _imageRate;}
@@ -76,7 +77,7 @@ protected:
/** /**
* returned rgb and depth images should be already rectified if calibration was loaded * returned rgb and depth images should be already rectified if calibration was loaded
*/ */
virtual SensorData captureImage() = 0; virtual SensorData captureImage(CameraInfo * info = 0) = 0;
int getNextSeqID() {return ++_seq;} int getNextSeqID() {return ++_seq;}

View File

@@ -1,5 +1,5 @@
/* /*
Copyright (c) 2010-2014, Mathieu Labbe - IntRoLab - Universite de Sherbrooke Copyright (c) 2010-2016, Mathieu Labbe - IntRoLab - Universite de Sherbrooke
All rights reserved. All rights reserved.
Redistribution and use in source and binary forms, with or without Redistribution and use in source and binary forms, with or without

View File

@@ -1,5 +1,5 @@
/* /*
Copyright (c) 2010-2014, Mathieu Labbe - IntRoLab - Universite de Sherbrooke Copyright (c) 2010-2016, Mathieu Labbe - IntRoLab - Universite de Sherbrooke
All rights reserved. All rights reserved.
Redistribution and use in source and binary forms, with or without Redistribution and use in source and binary forms, with or without
@@ -39,22 +39,33 @@ public:
CameraInfo() : CameraInfo() :
cameraName(""), cameraName(""),
id(0), id(0),
stamp(0.0),
timeCapture(0.0f), timeCapture(0.0f),
timeDisparity(0.0f), timeDisparity(0.0f),
timeMirroring(0.0f), timeMirroring(0.0f),
timeImageDecimation(0.0f), timeImageDecimation(0.0f),
timeScanFromDepth(0.0f) timeScanFromDepth(0.0f),
timeUndistortDepth(0.0f),
timeBilateralFiltering(0.0f),
timeTotal(0.0f),
odomCovariance(cv::Mat::eye(6,6,CV_64FC1))
{ {
} }
virtual ~CameraInfo() {} virtual ~CameraInfo() {}
std::string cameraName; std::string cameraName;
int id; int id;
double stamp;
float timeCapture; float timeCapture;
float timeDisparity; float timeDisparity;
float timeMirroring; float timeMirroring;
float timeImageDecimation; float timeImageDecimation;
float timeScanFromDepth; float timeScanFromDepth;
float timeUndistortDepth;
float timeBilateralFiltering;
float timeTotal;
Transform odomPose;
cv::Mat odomCovariance;
}; };
} // namespace rtabmap } // namespace rtabmap

View File

@@ -1,5 +1,5 @@
/* /*
Copyright (c) 2010-2014, Mathieu Labbe - IntRoLab - Universite de Sherbrooke Copyright (c) 2010-2016, Mathieu Labbe - IntRoLab - Universite de Sherbrooke
All rights reserved. All rights reserved.
Redistribution and use in source and binary forms, with or without Redistribution and use in source and binary forms, with or without
@@ -76,7 +76,8 @@ public:
void initRectificationMap(); void initRectificationMap();
bool isValidForProjection() const {return fx()>0.0 && fy()>0.0;} bool isValidForProjection() const {return fx()>0.0 && fy()>0.0 && cx()>0.0 && cy()>0.0;}
bool isValidForReprojection() const {return fx()>0.0 && fy()>0.0 && cx()>0.0 && cy()>0.0 && imageWidth()>0 && imageHeight()>0;}
bool isValidForRectification() const bool isValidForRectification() const
{ {
return imageSize_.width>0 && return imageSize_.width>0 &&
@@ -106,7 +107,7 @@ public:
void setLocalTransform(const Transform & transform) {localTransform_ = transform;} void setLocalTransform(const Transform & transform) {localTransform_ = transform;}
const Transform & localTransform() const {return localTransform_;} const Transform & localTransform() const {return localTransform_;}
void setImageSize(const cv::Size & size) {imageSize_ = size;} void setImageSize(const cv::Size & size);
const cv::Size & imageSize() const {return imageSize_;} const cv::Size & imageSize() const {return imageSize_;}
int imageWidth() const {return imageSize_.width;} int imageWidth() const {return imageSize_.width;}
int imageHeight() const {return imageSize_.height;} int imageHeight() const {return imageSize_.height;}
@@ -115,6 +116,7 @@ public:
bool save(const std::string & directory) const; bool save(const std::string & directory) const;
CameraModel scaled(double scale) const; CameraModel scaled(double scale) const;
CameraModel roi(const cv::Rect & roi) const;
double horizontalFOV() const; // in degrees double horizontalFOV() const; // in degrees
double verticalFOV() const; // in degrees double verticalFOV() const; // in degrees
@@ -123,6 +125,13 @@ public:
cv::Mat rectifyImage(const cv::Mat & raw, int interpolation = cv::INTER_LINEAR) const; cv::Mat rectifyImage(const cv::Mat & raw, int interpolation = cv::INTER_LINEAR) const;
cv::Mat rectifyDepth(const cv::Mat & raw) const; cv::Mat rectifyDepth(const cv::Mat & raw) const;
// Project 2D pixel to 3D (in /camera_link frame)
void project(float u, float v, float depth, float & x, float & y, float & z) const;
// Reproject 3D point (in /camera_link frame) to pixel
void reproject(float x, float y, float z, float & u, float & v) const;
void reproject(float x, float y, float z, int & u, int & v) const;
bool inFrame(int u, int v) const;
private: private:
std::string name_; std::string name_;
cv::Size imageSize_; cv::Size imageSize_;

View File

@@ -1,5 +1,5 @@
/* /*
Copyright (c) 2010-2014, Mathieu Labbe - IntRoLab - Universite de Sherbrooke Copyright (c) 2010-2016, Mathieu Labbe - IntRoLab - Universite de Sherbrooke
All rights reserved. All rights reserved.
Redistribution and use in source and binary forms, with or without Redistribution and use in source and binary forms, with or without
@@ -59,6 +59,7 @@ public:
virtual bool init(const std::string & calibrationFolder = ".", const std::string & cameraName = ""); virtual bool init(const std::string & calibrationFolder = ".", const std::string & cameraName = "");
virtual bool isCalibrated() const; virtual bool isCalibrated() const;
virtual std::string getSerial() const; virtual std::string getSerial() const;
virtual bool odomProvided() const { return odometry_.size() > 0; }
std::string getPath() const {return _path;} std::string getPath() const {return _path;}
unsigned int imagesCount() const; unsigned int imagesCount() const;
std::vector<std::string> filenames() const; std::vector<std::string> filenames() const;
@@ -75,8 +76,8 @@ public:
void setTimestamps(bool fileNamesAreStamps, const std::string & filePath = "", bool syncImageRateWithStamps=true) void setTimestamps(bool fileNamesAreStamps, const std::string & filePath = "", bool syncImageRateWithStamps=true)
{ {
_filenamesAreTimestamps = fileNamesAreStamps; _filenamesAreTimestamps = fileNamesAreStamps;
timestampsPath_=filePath; _timestampsPath=filePath;
syncImageRateWithStamps_ = syncImageRateWithStamps; _syncImageRateWithStamps = syncImageRateWithStamps;
} }
void setScanPath( void setScanPath(
@@ -106,9 +107,15 @@ public:
_depthFromScanFillHolesFromBorder = fillHolesFromBorder; _depthFromScanFillHolesFromBorder = fillHolesFromBorder;
} }
void setOdometryPath(const std::string & filePath, int format = 0)
{
_odometryPath = filePath;
_odometryFormat = format;
}
void setGroundTruthPath(const std::string & filePath, int format = 0) void setGroundTruthPath(const std::string & filePath, int format = 0)
{ {
groundTruthPath_ = filePath; _groundTruthPath = filePath;
_groundTruthFormat = format; _groundTruthFormat = format;
} }
@@ -119,7 +126,8 @@ public:
} }
protected: protected:
virtual SensorData captureImage(); virtual SensorData captureImage(CameraInfo * info = 0);
bool readPoses(std::list<Transform> & outputPoses, std::list<double> & stamps, const std::string & filePath, int format) const;
private: private:
std::string _path; std::string _path;
@@ -150,13 +158,17 @@ private:
bool _depthFromScanFillHolesFromBorder; bool _depthFromScanFillHolesFromBorder;
bool _filenamesAreTimestamps; bool _filenamesAreTimestamps;
std::string timestampsPath_; std::string _timestampsPath;
bool syncImageRateWithStamps_; bool _syncImageRateWithStamps;
std::string groundTruthPath_; std::string _odometryPath;
int _odometryFormat;
std::string _groundTruthPath;
int _groundTruthFormat; int _groundTruthFormat;
std::list<double> stamps_; std::list<double> _stamps;
std::list<Transform> odometry_;
std::list<Transform> groundTruth_; std::list<Transform> groundTruth_;
CameraModel _model; CameraModel _model;
@@ -178,6 +190,7 @@ public:
public: public:
CameraVideo(int usbDevice = 0, CameraVideo(int usbDevice = 0,
bool rectifyImages = false,
float imageRate = 0, float imageRate = 0,
const Transform & localTransform = Transform::getIdentity()); const Transform & localTransform = Transform::getIdentity());
CameraVideo(const std::string & filePath, CameraVideo(const std::string & filePath,
@@ -193,7 +206,7 @@ public:
const std::string & getFilePath() const {return _filePath;} const std::string & getFilePath() const {return _filePath;}
protected: protected:
virtual SensorData captureImage(); virtual SensorData captureImage(CameraInfo * info = 0);
private: private:
// File type // File type

View File

@@ -1,5 +1,5 @@
/* /*
Copyright (c) 2010-2014, Mathieu Labbe - IntRoLab - Universite de Sherbrooke Copyright (c) 2010-2016, Mathieu Labbe - IntRoLab - Universite de Sherbrooke
All rights reserved. All rights reserved.
Redistribution and use in source and binary forms, with or without Redistribution and use in source and binary forms, with or without
@@ -34,6 +34,7 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include "rtabmap/core/CameraModel.h" #include "rtabmap/core/CameraModel.h"
#include "rtabmap/core/Camera.h" #include "rtabmap/core/Camera.h"
#include "rtabmap/core/CameraRGB.h" #include "rtabmap/core/CameraRGB.h"
#include "rtabmap/core/Version.h"
#include <pcl/pcl_config.h> #include <pcl/pcl_config.h>
@@ -64,6 +65,12 @@ class Registration;
class PacketPipeline; class PacketPipeline;
} }
namespace rs
{
class context;
class device;
}
typedef struct _freenect_context freenect_context; typedef struct _freenect_context freenect_context;
typedef struct _freenect_device freenect_device; typedef struct _freenect_device freenect_device;
@@ -97,7 +104,7 @@ public:
virtual std::string getSerial() const; virtual std::string getSerial() const;
protected: protected:
virtual SensorData captureImage(); virtual SensorData captureImage(CameraInfo * info = 0);
private: private:
pcl::Grabber* interface_; pcl::Grabber* interface_;
@@ -131,7 +138,7 @@ public:
virtual std::string getSerial() const {return "";} // unknown with OpenCV virtual std::string getSerial() const {return "";} // unknown with OpenCV
protected: protected:
virtual SensorData captureImage(); virtual SensorData captureImage(CameraInfo * info = 0);
private: private:
bool _asus; bool _asus;
@@ -149,9 +156,11 @@ class RTABMAP_EXP CameraOpenNI2 :
public: public:
static bool available(); static bool available();
static bool exposureGainAvailable(); static bool exposureGainAvailable();
enum Type {kTypeColorDepth, kTypeIRDepth, kTypeIR};
public: public:
CameraOpenNI2(const std::string & deviceId = "", CameraOpenNI2(const std::string & deviceId = "",
Type type = kTypeColorDepth,
float imageRate = 0, float imageRate = 0,
const Transform & localTransform = Transform::getIdentity()); const Transform & localTransform = Transform::getIdentity());
virtual ~CameraOpenNI2(); virtual ~CameraOpenNI2();
@@ -165,12 +174,14 @@ public:
bool setExposure(int value); bool setExposure(int value);
bool setGain(int value); bool setGain(int value);
bool setMirroring(bool enabled); bool setMirroring(bool enabled);
void setOpenNI2StampsAndIDsUsed(bool used) {_openNI2StampsAndIDsUsed = used;} void setOpenNI2StampsAndIDsUsed(bool used);
protected: protected:
virtual SensorData captureImage(); virtual SensorData captureImage(CameraInfo * info = 0);
private: private:
#ifdef RTABMAP_OPENNI2
Type _type;
openni::Device * _device; openni::Device * _device;
openni::VideoStream * _color; openni::VideoStream * _color;
openni::VideoStream * _depth; openni::VideoStream * _depth;
@@ -178,6 +189,8 @@ private:
float _depthFy; float _depthFy;
std::string _deviceId; std::string _deviceId;
bool _openNI2StampsAndIDsUsed; bool _openNI2StampsAndIDsUsed;
StereoCameraModel _stereoModel;
#endif
}; };
@@ -191,10 +204,12 @@ class RTABMAP_EXP CameraFreenect :
{ {
public: public:
static bool available(); static bool available();
enum Type {kTypeColorDepth, kTypeIRDepth};
public: public:
// default local transform z in, x right, y down)); // default local transform z in, x right, y down));
CameraFreenect(int deviceId= 0, CameraFreenect(int deviceId= 0,
Type type = kTypeColorDepth,
float imageRate=0.0f, float imageRate=0.0f,
const Transform & localTransform = Transform::getIdentity()); const Transform & localTransform = Transform::getIdentity());
virtual ~CameraFreenect(); virtual ~CameraFreenect();
@@ -204,12 +219,16 @@ public:
virtual std::string getSerial() const; virtual std::string getSerial() const;
protected: protected:
virtual SensorData captureImage(); virtual SensorData captureImage(CameraInfo * info = 0);
private: private:
#ifdef RTABMAP_FREENECT
int deviceId_; int deviceId_;
Type type_;
freenect_context * ctx_; freenect_context * ctx_;
FreenectDevice * freenectDevice_; FreenectDevice * freenectDevice_;
StereoCameraModel stereoModel_;
#endif
}; };
///////////////////////// /////////////////////////
@@ -249,9 +268,10 @@ public:
virtual std::string getSerial() const; virtual std::string getSerial() const;
protected: protected:
virtual SensorData captureImage(); virtual SensorData captureImage(CameraInfo * info = 0);
private: private:
#ifdef RTABMAP_FREENECT2
int deviceId_; int deviceId_;
Type type_; Type type_;
StereoCameraModel stereoModel_; StereoCameraModel stereoModel_;
@@ -264,6 +284,43 @@ private:
bool bilateralFiltering_; bool bilateralFiltering_;
bool edgeAwareFiltering_; bool edgeAwareFiltering_;
bool noiseFiltering_; bool noiseFiltering_;
#endif
};
/////////////////////////
// CameraRealSense
/////////////////////////
class RTABMAP_EXP CameraRealSense :
public Camera
{
public:
static bool available();
public:
// default local transform z in, x right, y down));
CameraRealSense(
int deviceId = 0,
int presetRGB = 0, // 0=best quality, 1=largest image, 2=highest framerate
int presetDepth = 0, // 0=best quality, 1=largest image, 2=highest framerate
float imageRate = 0,
const Transform & localTransform = Transform::getIdentity());
virtual ~CameraRealSense();
virtual bool init(const std::string & calibrationFolder = ".", const std::string & cameraName = "");
virtual bool isCalibrated() const;
virtual std::string getSerial() const;
protected:
virtual SensorData captureImage(CameraInfo * info = 0);
private:
#ifdef RTABMAP_REALSENSE
rs::context * ctx_;
rs::device * dev_;
int deviceId_;
int presetRGB_;
int presetDepth_;
#endif
}; };
@@ -291,7 +348,7 @@ public:
virtual std::string getSerial() const; virtual std::string getSerial() const;
protected: protected:
virtual SensorData captureImage(); virtual SensorData captureImage(CameraInfo * info = 0);
private: private:
CameraImages cameraDepth_; CameraImages cameraDepth_;

View File

@@ -1,5 +1,5 @@
/* /*
Copyright (c) 2010-2014, Mathieu Labbe - IntRoLab - Universite de Sherbrooke Copyright (c) 2010-2016, Mathieu Labbe - IntRoLab - Universite de Sherbrooke
All rights reserved. All rights reserved.
Redistribution and use in source and binary forms, with or without Redistribution and use in source and binary forms, with or without
@@ -32,6 +32,7 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include "rtabmap/core/CameraModel.h" #include "rtabmap/core/CameraModel.h"
#include "rtabmap/core/Camera.h" #include "rtabmap/core/Camera.h"
#include "rtabmap/core/CameraRGB.h" #include "rtabmap/core/CameraRGB.h"
#include "rtabmap/core/Version.h"
#include <list> #include <list>
namespace FlyCapture2 namespace FlyCapture2
@@ -70,11 +71,13 @@ public:
virtual std::string getSerial() const; virtual std::string getSerial() const;
protected: protected:
virtual SensorData captureImage(); virtual SensorData captureImage(CameraInfo * info = 0);
private: private:
#ifdef RTABMAP_DC1394
DC1394Device *device_; DC1394Device *device_;
StereoCameraModel stereoModel_; StereoCameraModel stereoModel_;
#endif
}; };
///////////////////////// /////////////////////////
@@ -95,11 +98,13 @@ public:
virtual std::string getSerial() const; virtual std::string getSerial() const;
protected: protected:
virtual SensorData captureImage(); virtual SensorData captureImage(CameraInfo * info = 0);
private: private:
#ifdef RTABMAP_FLYCAPTURE2
FlyCapture2::Camera * camera_; FlyCapture2::Camera * camera_;
void * triclopsCtx_; // TriclopsContext void * triclopsCtx_; // TriclopsContext
#endif
}; };
///////////////////////// /////////////////////////
@@ -112,20 +117,50 @@ public:
static bool available(); static bool available();
public: public:
CameraStereoZed(bool rgbdMode, float imageRate=0.0f, const Transform & localTransform = Transform::getIdentity()); CameraStereoZed(
int deviceId,
int resolution = 2, // 0=HD2K, 1=HD1080, 2=HD720, 3=VGA
int quality = 1, // 0=NONE, 1=PERFORMANCE, 2=QUALITY
int sensingMode = 1,// 0=FULL, 1=RAW
int confidenceThr = 100,
bool computeOdometry = false,
float imageRate=0.0f,
const Transform & localTransform = Transform::getIdentity(),
bool selfCalibration = false);
CameraStereoZed(
const std::string & svoFilePath,
int quality = 1, // 0=NONE, 1=PERFORMANCE, 2=QUALITY
int sensingMode = 1,// 0=FULL, 1=RAW
int confidenceThr = 100,
bool computeOdometry = false,
float imageRate=0.0f,
const Transform & localTransform = Transform::getIdentity(),
bool selfCalibration = false);
virtual ~CameraStereoZed(); virtual ~CameraStereoZed();
virtual bool init(const std::string & calibrationFolder = ".", const std::string & cameraName = ""); virtual bool init(const std::string & calibrationFolder = ".", const std::string & cameraName = "");
virtual bool isCalibrated() const; virtual bool isCalibrated() const;
virtual std::string getSerial() const; virtual std::string getSerial() const;
virtual bool odomProvided() const;
protected: protected:
virtual SensorData captureImage(); virtual SensorData captureImage(CameraInfo * info = 0);
private: private:
#ifdef RTABMAP_ZED
sl::zed::Camera * zed_; sl::zed::Camera * zed_;
StereoCameraModel stereoModel_; StereoCameraModel stereoModel_;
bool rgbdMode_; CameraVideo::Source src_;
int usbDevice_;
std::string svoFilePath_;
int resolution_;
int quality_;
bool selfCalibration_;
int sensingMode_;
int confidenceThr_;
bool computeOdometry_;
bool lost_;
#endif
}; };
///////////////////////// /////////////////////////
@@ -157,7 +192,7 @@ public:
virtual std::string getSerial() const; virtual std::string getSerial() const;
protected: protected:
virtual SensorData captureImage(); virtual SensorData captureImage(CameraInfo * info = 0);
private: private:
CameraImages * camera2_; CameraImages * camera2_;
@@ -177,12 +212,19 @@ public:
public: public:
CameraStereoVideo( CameraStereoVideo(
const std::string & path, const std::string & pathSideBySide,
bool rectifyImages = false,
float imageRate=0.0f,
const Transform & localTransform = Transform::getIdentity());
CameraStereoVideo(
const std::string & pathLeft,
const std::string & pathRight,
bool rectifyImages = false, bool rectifyImages = false,
float imageRate=0.0f, float imageRate=0.0f,
const Transform & localTransform = Transform::getIdentity()); const Transform & localTransform = Transform::getIdentity());
CameraStereoVideo( CameraStereoVideo(
int device, int device,
bool rectifyImages = false,
float imageRate = 0.0f, float imageRate = 0.0f,
const Transform & localTransform = Transform::getIdentity()); const Transform & localTransform = Transform::getIdentity());
virtual ~CameraStereoVideo(); virtual ~CameraStereoVideo();
@@ -192,11 +234,13 @@ public:
virtual std::string getSerial() const; virtual std::string getSerial() const;
protected: protected:
virtual SensorData captureImage(); virtual SensorData captureImage(CameraInfo * info = 0);
private: private:
cv::VideoCapture capture_; cv::VideoCapture capture_;
cv::VideoCapture capture2_;
std::string path_; std::string path_;
std::string path2_;
bool rectifyImages_; bool rectifyImages_;
StereoCameraModel stereoModel_; StereoCameraModel stereoModel_;
std::string cameraName_; std::string cameraName_;

View File

@@ -1,5 +1,5 @@
/* /*
Copyright (c) 2010-2014, Mathieu Labbe - IntRoLab - Universite de Sherbrooke Copyright (c) 2010-2016, Mathieu Labbe - IntRoLab - Universite de Sherbrooke
All rights reserved. All rights reserved.
Redistribution and use in source and binary forms, with or without Redistribution and use in source and binary forms, with or without
@@ -33,6 +33,11 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include <rtabmap/utilite/UThread.h> #include <rtabmap/utilite/UThread.h>
#include <rtabmap/utilite/UEventsSender.h> #include <rtabmap/utilite/UEventsSender.h>
namespace clams
{
class DiscreteDepthDistortionModel;
}
namespace rtabmap namespace rtabmap
{ {
@@ -56,6 +61,10 @@ public:
void setColorOnly(bool colorOnly) {_colorOnly = colorOnly;} void setColorOnly(bool colorOnly) {_colorOnly = colorOnly;}
void setImageDecimation(int decimation) {_imageDecimation = decimation;} void setImageDecimation(int decimation) {_imageDecimation = decimation;}
void setStereoToDepth(bool enabled) {_stereoToDepth = enabled;} void setStereoToDepth(bool enabled) {_stereoToDepth = enabled;}
void setImageRate(float imageRate);
void setDistortionModel(const std::string & path);
void enableBilateralFiltering(float sigmaS, float sigmaR);
void disableBilateralFiltering() {_bilateralFiltering = false;}
void setScanFromDepth( void setScanFromDepth(
bool enabled, bool enabled,
@@ -74,11 +83,11 @@ public:
//getters //getters
bool isPaused() const {return !this->isRunning();} bool isPaused() const {return !this->isRunning();}
bool isCapturing() const {return this->isRunning();} bool isCapturing() const {return this->isRunning();}
void setImageRate(float imageRate);
Camera * camera() {return _camera;} // return null if not set, valid until CameraThread is deleted Camera * camera() {return _camera;} // return null if not set, valid until CameraThread is deleted
private: private:
virtual void mainLoopBegin();
virtual void mainLoop(); virtual void mainLoop();
virtual void mainLoopKill(); virtual void mainLoopKill();
@@ -95,6 +104,10 @@ private:
float _scanVoxelSize; float _scanVoxelSize;
int _scanNormalsK; int _scanNormalsK;
StereoDense * _stereoDense; StereoDense * _stereoDense;
clams::DiscreteDepthDistortionModel * _distortionModel;
bool _bilateralFiltering;
float _bilateralSigmaS;
float _bilateralSigmaR;
}; };
} // namespace rtabmap } // namespace rtabmap

View File

@@ -1,5 +1,5 @@
/* /*
Copyright (c) 2010-2014, Mathieu Labbe - IntRoLab - Universite de Sherbrooke Copyright (c) 2010-2016, Mathieu Labbe - IntRoLab - Universite de Sherbrooke
All rights reserved. All rights reserved.
Redistribution and use in source and binary forms, with or without Redistribution and use in source and binary forms, with or without

View File

@@ -1,5 +1,5 @@
/* /*
Copyright (c) 2010-2014, Mathieu Labbe - IntRoLab - Universite de Sherbrooke Copyright (c) 2010-2016, Mathieu Labbe - IntRoLab - Universite de Sherbrooke
All rights reserved. All rights reserved.
Redistribution and use in source and binary forms, with or without Redistribution and use in source and binary forms, with or without
@@ -39,6 +39,7 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include "rtabmap/utilite/UThreadNode.h" #include "rtabmap/utilite/UThreadNode.h"
#include "rtabmap/core/Parameters.h" #include "rtabmap/core/Parameters.h"
#include "rtabmap/core/SensorData.h" #include "rtabmap/core/SensorData.h"
#include <rtabmap/core/Statistics.h>
#include <rtabmap/core/Transform.h> #include <rtabmap/core/Transform.h>
#include <rtabmap/core/Link.h> #include <rtabmap/core/Link.h>
@@ -86,15 +87,22 @@ public:
void addLink(const Link & link); void addLink(const Link & link);
void removeLink(int from, int to); void removeLink(int from, int to);
void updateLink(const Link & link); void updateLink(const Link & link);
void updateOccupancyGrid(
int nodeId,
const cv::Mat & ground,
const cv::Mat & obstacles,
float cellSize,
const cv::Point3f & viewpoint);
public: public:
void addStatisticsAfterRun(int stMemSize, int lastSignAdded, int processMemUsed, int databaseMemUsed, int dictionarySize) const; void addInfoAfterRun(int stMemSize, int lastSignAdded, int processMemUsed, int databaseMemUsed, int dictionarySize, const ParametersMap & parameters) const;
void addStatistics(const Statistics & statistics) const;
public: public:
// Mutex-protected methods of abstract versions below // Mutex-protected methods of abstract versions below
bool openConnection(const std::string & url, bool overwritten = false); bool openConnection(const std::string & url, bool overwritten = false);
void closeConnection(bool save = true); void closeConnection(bool save = true, const std::string & outputUrl = "");
bool isConnected() const; bool isConnected() const;
long getMemoryUsed() const; // In bytes long getMemoryUsed() const; // In bytes
std::string getDatabaseVersion() const; std::string getDatabaseVersion() const;
@@ -107,6 +115,8 @@ public:
int getLastDictionarySize() const; // working memory int getLastDictionarySize() const; // working memory
int getTotalNodesSize() const; int getTotalNodesSize() const;
int getTotalDictionarySize() const; int getTotalDictionarySize() const;
ParametersMap getLastParameters() const;
std::map<std::string, float> getStatistics(int nodeId, double & stamp) const;
void executeNoResult(const std::string & sql) const; void executeNoResult(const std::string & sql) const;
@@ -117,8 +127,8 @@ public:
void loadWords(const std::set<int> & wordIds, std::list<VisualWord *> & vws); void loadWords(const std::set<int> & wordIds, std::list<VisualWord *> & vws);
// Specific queries... // Specific queries...
void loadNodeData(std::list<Signature *> & signatures) 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) 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, StereoCameraModel & stereoModel) const;
bool getNodeInfo(int signatureId, Transform & pose, int & mapId, int & weight, std::string & label, double & stamp, Transform & groundTruthPose) const; bool getNodeInfo(int signatureId, Transform & pose, int & mapId, int & weight, std::string & label, double & stamp, Transform & groundTruthPose) const;
void loadLinks(int signatureId, std::map<int, Link> & links, Link::Type type = Link::kUndef) const; void loadLinks(int signatureId, std::map<int, Link> & links, Link::Type type = Link::kUndef) const;
@@ -136,7 +146,7 @@ protected:
private: private:
virtual bool connectDatabaseQuery(const std::string & url, bool overwritten = false) = 0; virtual bool connectDatabaseQuery(const std::string & url, bool overwritten = false) = 0;
virtual void disconnectDatabaseQuery(bool save = true) = 0; virtual void disconnectDatabaseQuery(bool save = true, const std::string & outputUrl = "") = 0;
virtual bool isConnectedQuery() const = 0; virtual bool isConnectedQuery() const = 0;
virtual long getMemoryUsedQuery() const = 0; // In bytes virtual long getMemoryUsedQuery() const = 0; // In bytes
virtual bool getDatabaseVersionQuery(std::string & version) const = 0; virtual bool getDatabaseVersionQuery(std::string & version) const = 0;
@@ -149,6 +159,8 @@ private:
virtual int getLastDictionarySizeQuery() const = 0; virtual int getLastDictionarySizeQuery() const = 0;
virtual int getTotalNodesSizeQuery() const = 0; virtual int getTotalNodesSizeQuery() const = 0;
virtual int getTotalDictionarySizeQuery() const = 0; virtual int getTotalDictionarySizeQuery() const = 0;
virtual ParametersMap getLastParametersQuery() const = 0;
virtual std::map<std::string, float> getStatisticsQuery(int nodeId, double & stamp) const = 0;
virtual void executeNoResultQuery(const std::string & sql) const = 0; virtual void executeNoResultQuery(const std::string & sql) const = 0;
@@ -162,6 +174,15 @@ private:
virtual void addLinkQuery(const Link & link) const = 0; virtual void addLinkQuery(const Link & link) const = 0;
virtual void updateLinkQuery(const Link & link) const = 0; virtual void updateLinkQuery(const Link & link) const = 0;
virtual void updateOccupancyGridQuery(
int nodeId,
const cv::Mat & ground,
const cv::Mat & obstacles,
float cellSize,
const cv::Point3f & viewpoint) const = 0;
virtual void addStatisticsQuery(const Statistics & statistics) const = 0;
// Load objects // Load objects
virtual void loadQuery(VWDictionary * dictionary) const = 0; virtual void loadQuery(VWDictionary * dictionary) const = 0;
virtual void loadLastNodesQuery(std::list<Signature *> & signatures) const = 0; virtual void loadLastNodesQuery(std::list<Signature *> & signatures) const = 0;
@@ -169,7 +190,7 @@ private:
virtual void loadWordsQuery(const std::set<int> & wordIds, std::list<VisualWord *> & vws) const = 0; virtual void loadWordsQuery(const std::set<int> & wordIds, std::list<VisualWord *> & vws) const = 0;
virtual void loadLinksQuery(int signatureId, std::map<int, Link> & links, Link::Type type = Link::kUndef) const = 0; virtual void loadLinksQuery(int signatureId, std::map<int, Link> & links, Link::Type type = Link::kUndef) const = 0;
virtual void loadNodeDataQuery(std::list<Signature *> & signatures) 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, StereoCameraModel & stereoModel) const = 0;
virtual bool getNodeInfoQuery(int signatureId, Transform & pose, int & mapId, int & weight, std::string & label, double & stamp, Transform & groundTruthPose) const = 0; virtual bool getNodeInfoQuery(int signatureId, Transform & pose, int & mapId, int & weight, std::string & label, double & stamp, Transform & groundTruthPose) const = 0;
virtual void getAllNodeIdsQuery(std::set<int> & ids, bool ignoreChildren, bool ignoreBadSignatures) const = 0; virtual void getAllNodeIdsQuery(std::set<int> & ids, bool ignoreChildren, bool ignoreBadSignatures) const = 0;

View File

@@ -1,5 +1,5 @@
/* /*
Copyright (c) 2010-2014, Mathieu Labbe - IntRoLab - Universite de Sherbrooke Copyright (c) 2010-2016, Mathieu Labbe - IntRoLab - Universite de Sherbrooke
All rights reserved. All rights reserved.
Redistribution and use in source and binary forms, with or without Redistribution and use in source and binary forms, with or without
@@ -30,11 +30,9 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include "rtabmap/core/RtabmapExp.h" // DLL export/import defines #include "rtabmap/core/RtabmapExp.h" // DLL export/import defines
#include <rtabmap/utilite/UThreadNode.h>
#include <rtabmap/utilite/UTimer.h> #include <rtabmap/utilite/UTimer.h>
#include <rtabmap/utilite/UEventsSender.h>
#include <rtabmap/core/Transform.h> #include <rtabmap/core/Transform.h>
#include <rtabmap/core/OdometryEvent.h> #include <rtabmap/core/Camera.h>
#include <opencv2/core/core.hpp> #include <opencv2/core/core.hpp>
@@ -45,34 +43,45 @@ namespace rtabmap {
class DBDriver; class DBDriver;
class RTABMAP_EXP DBReader : public UThreadNode, public UEventsSender { class RTABMAP_EXP DBReader : public Camera {
public: public:
DBReader(const std::string & databasePath, DBReader(const std::string & databasePath,
float frameRate = 0.0f, float frameRate = 0.0f, // -1 = use Database stamps, 0 = inf
bool odometryIgnored = false, bool odometryIgnored = false,
bool ignoreGoalDelay = false, bool ignoreGoalDelay = false,
bool goalsIgnored = false); bool goalsIgnored = false,
int startIndex = 0,
int cameraIndex = -1);
DBReader(const std::list<std::string> & databasePaths, DBReader(const std::list<std::string> & databasePaths,
float frameRate = 0.0f, float frameRate = 0.0f, // -1 = use Database stamps, 0 = inf
bool odometryIgnored = false, bool odometryIgnored = false,
bool ignoreGoalDelay = false, bool ignoreGoalDelay = false,
bool goalsIgnored = false); bool goalsIgnored = false,
int startIndex = 0,
int cameraIndex = -1);
virtual ~DBReader(); virtual ~DBReader();
bool init(int startIndex=0); virtual bool init(
void setFrameRate(float frameRate); const std::string & calibrationFolder = ".",
OdometryEvent getNextData(); const std::string & cameraName = "");
virtual bool isCalibrated() const;
virtual std::string getSerial() const;
virtual bool odomProvided() const {return !_odometryIgnored;}
protected: protected:
virtual void mainLoopBegin(); virtual SensorData captureImage(CameraInfo * info = 0);
virtual void mainLoop();
private:
SensorData getNextData(CameraInfo * info = 0);
private: private:
std::list<std::string> _paths; std::list<std::string> _paths;
float _frameRate; // -1 = use Database stamps, 0 = inf
bool _odometryIgnored; bool _odometryIgnored;
bool _ignoreGoalDelay; bool _ignoreGoalDelay;
bool _goalsIgnored; bool _goalsIgnored;
int _startIndex;
int _cameraIndex;
DBDriver * _dbDriver; DBDriver * _dbDriver;
UTimer _timer; UTimer _timer;
@@ -80,6 +89,7 @@ private:
std::set<int>::iterator _currentId; std::set<int>::iterator _currentId;
double _previousStamp; double _previousStamp;
int _previousMapID; int _previousMapID;
bool _calibrated;
}; };
} /* namespace rtabmap */ } /* namespace rtabmap */

View File

@@ -1,5 +1,5 @@
/* /*
Copyright (c) 2010-2014, Mathieu Labbe - IntRoLab - Universite de Sherbrooke Copyright (c) 2010-2016, Mathieu Labbe - IntRoLab - Universite de Sherbrooke
All rights reserved. All rights reserved.
Redistribution and use in source and binary forms, with or without Redistribution and use in source and binary forms, with or without

View File

@@ -1,5 +1,5 @@
/* /*
Copyright (c) 2010-2014, Mathieu Labbe - IntRoLab - Universite de Sherbrooke Copyright (c) 2010-2016, Mathieu Labbe - IntRoLab - Universite de Sherbrooke
All rights reserved. All rights reserved.
Redistribution and use in source and binary forms, with or without Redistribution and use in source and binary forms, with or without
@@ -133,6 +133,7 @@ public:
static void limitKeypoints(std::vector<cv::KeyPoint> & keypoints, int maxKeypoints); static void limitKeypoints(std::vector<cv::KeyPoint> & keypoints, int maxKeypoints);
static void limitKeypoints(std::vector<cv::KeyPoint> & keypoints, cv::Mat & descriptors, int maxKeypoints); static void limitKeypoints(std::vector<cv::KeyPoint> & keypoints, cv::Mat & descriptors, int maxKeypoints);
static void limitKeypoints(std::vector<cv::KeyPoint> & keypoints, std::vector<cv::Point3f> & keypoints3D, cv::Mat & descriptors, int maxKeypoints);
static cv::Rect computeRoi(const cv::Mat & image, const std::string & roiRatios); static cv::Rect computeRoi(const cv::Mat & image, const std::string & roiRatios);
static cv::Rect computeRoi(const cv::Mat & image, const std::vector<float> & roiRatios); static cv::Rect computeRoi(const cv::Mat & image, const std::vector<float> & roiRatios);

View File

@@ -0,0 +1,114 @@
/*
Copyright (c) 2010-2016, Mathieu Labbe - IntRoLab - Universite de Sherbrooke
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
* Neither the name of the Universite de Sherbrooke nor the
names of its contributors may be used to endorse or promote products
derived from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef CORELIB_SRC_FLANNINDEX_H_
#define CORELIB_SRC_FLANNINDEX_H_
#include "rtabmap/core/RtabmapExp.h" // DLL export/import defines
#include <list>
#include <opencv2/opencv.hpp>
namespace rtabmap {
class RTABMAP_EXP FlannIndex
{
public:
FlannIndex();
virtual ~FlannIndex();
void release();
unsigned int indexedFeatures() const;
// return KB
unsigned int memoryUsed() const;
// Note that useDistanceL1 doesn't have any effect if LSH is used
void buildLinearIndex(
const cv::Mat & features,
bool useDistanceL1 = false);
void buildKDTreeIndex(
const cv::Mat & features,
int trees = 4,
bool useDistanceL1 = false);
void buildKDTreeSingleIndex(
const cv::Mat & features,
int leafMaxSize = 10,
bool reorder = true,
bool useDistanceL1 = false);
void buildLSHIndex(
const cv::Mat & features,
unsigned int table_number = 12,
unsigned int key_size = 20,
unsigned int multi_probe_level = 2);
bool isBuilt();
int featuresType() const {return featuresType_;}
int featuresDim() const {return featuresDim_;}
unsigned int addPoints(const cv::Mat & features);
void removePoint(unsigned int index);
// return squared distances
void knnSearch(
const cv::Mat & query,
cv::Mat & indices,
cv::Mat & dists,
int knn,
int checks = 32,
float eps = 0.0,
bool sorted = true) const;
// return squared distances
void radiusSearch(
const cv::Mat & query,
std::vector<std::vector<size_t> > & indices,
std::vector<std::vector<float> > & dists,
float radius,
int maxNeighbors = 0,
int checks = 32,
float eps = 0.0,
bool sorted = true) const;
private:
void * index_;
unsigned int nextIndex_;
int featuresType_;
int featuresDim_;
bool isLSH_;
bool useDistanceL1_; // true=EUCLEDIAN_L2 false=MANHATTAN_L1
// keep feature in memory until the tree is rebuilt
// (in case the word is deleted when removed from the VWDictionary)
std::map<int, cv::Mat> addedDescriptors_;
std::list<int> removedIndexes_;
};
} /* namespace rtabmap */
#endif /* CORELIB_SRC_FLANNINDEX_H_ */

View File

@@ -0,0 +1,104 @@
/*
Copyright (c) 2010-2016, Mathieu Labbe - IntRoLab - Universite de Sherbrooke
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
* Neither the name of the Universite de Sherbrooke nor the
names of its contributors may be used to endorse or promote products
derived from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef CORELIB_SRC_GAINCOMPENSATOR_H_
#define CORELIB_SRC_GAINCOMPENSATOR_H_
#include "rtabmap/core/RtabmapExp.h" // DLL export/import defines
#include <pcl/point_cloud.h>
#include <pcl/point_types.h>
#include <pcl/pcl_base.h>
#include <opencv2/opencv.hpp>
#include <rtabmap/core/Link.h>
namespace rtabmap {
/**
* Works like cv::GainCompensator but with point clouds
*/
class RTABMAP_EXP GainCompensator {
public:
GainCompensator(double maxCorrespondenceDistance = 0.02, double minOverlap = 0.05, double alpha = 0.01, double beta = 10);
virtual ~GainCompensator();
void feed(
const pcl::PointCloud<pcl::PointXYZRGB>::Ptr & cloudA, // should not contain NaNs
const pcl::PointCloud<pcl::PointXYZRGB>::Ptr & cloudB, // should not contain NaNs
const Transform & transformB);
void feed(
const pcl::PointCloud<pcl::PointXYZRGB>::Ptr & cloudA,
const pcl::IndicesPtr & indicesA,
const pcl::PointCloud<pcl::PointXYZRGB>::Ptr & cloudB,
const pcl::IndicesPtr & indicesB,
const Transform & transformB);
void feed(
const std::map<int, pcl::PointCloud<pcl::PointXYZRGB>::Ptr> & clouds, // should not contain NaNs
const std::multimap<int, Link> & links);
void feed(
const std::map<int, pcl::PointCloud<pcl::PointXYZRGB>::Ptr> & clouds,
const std::map<int, pcl::IndicesPtr> & indices,
const std::multimap<int, Link> & links);
void feed(
const std::map<int, pcl::PointCloud<pcl::PointXYZRGBNormal>::Ptr> & clouds,
const std::map<int, pcl::IndicesPtr> & indices,
const std::multimap<int, Link> & links);
void feed(
const std::map<int, std::pair<pcl::PointCloud<pcl::PointXYZRGBNormal>::Ptr, pcl::IndicesPtr> > & clouds,
const std::multimap<int, Link> & links);
void apply(
int id,
pcl::PointCloud<pcl::PointXYZRGB>::Ptr & cloud);
void apply(
int id,
pcl::PointCloud<pcl::PointXYZRGB>::Ptr & cloud,
const pcl::IndicesPtr & indices);
void apply(
int id,
pcl::PointCloud<pcl::PointXYZRGBNormal>::Ptr & cloud,
const pcl::IndicesPtr & indices);
void apply(
int id,
cv::Mat & image);
double getGain(int id) const;
int getIndex(int id) const;
private:
cv::Mat_<double> gains_;
std::map<int, int> idToIndex_;
double maxCorrespondenceDistance_;
double minOverlap_;
double alpha_;
double beta_;
};
} /* namespace rtabmap */
#endif /* CORELIB_SRC_GAINCOMPENSATOR_H_ */

View File

@@ -1,5 +1,5 @@
/* /*
Copyright (c) 2010-2014, Mathieu Labbe - IntRoLab - Universite de Sherbrooke Copyright (c) 2010-2016, Mathieu Labbe - IntRoLab - Universite de Sherbrooke
All rights reserved. All rights reserved.
Redistribution and use in source and binary forms, with or without Redistribution and use in source and binary forms, with or without

View File

@@ -1,5 +1,5 @@
/* /*
Copyright (c) 2010-2014, Mathieu Labbe - IntRoLab - Universite de Sherbrooke Copyright (c) 2010-2016, Mathieu Labbe - IntRoLab - Universite de Sherbrooke
All rights reserved. All rights reserved.
Redistribution and use in source and binary forms, with or without Redistribution and use in source and binary forms, with or without

View File

@@ -0,0 +1,65 @@
/*
Copyright (c) 2010-2016, Mathieu Labbe - IntRoLab - Universite de Sherbrooke
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
* Neither the name of the Universite de Sherbrooke nor the
names of its contributors may be used to endorse or promote products
derived from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef CORELIB_INCLUDE_RTABMAP_CORE_LASERSCANINFO_H_
#define CORELIB_INCLUDE_RTABMAP_CORE_LASERSCANINFO_H_
#include <rtabmap/utilite/ULogger.h>
namespace rtabmap {
class LaserScanInfo
{
public:
LaserScanInfo() :
maxPoints_(0),
maxRange_(0),
localTransform_(Transform::getIdentity())
{
}
LaserScanInfo(int maxPoints, float maxRange, const Transform & localTransform = Transform::getIdentity()) :
maxPoints_(maxPoints),
maxRange_(maxRange),
localTransform_(localTransform)
{
UASSERT(!localTransform.isNull());
}
int maxPoints() const {return maxPoints_;}
float maxRange() const {return maxRange_;}
Transform localTransform() const {return localTransform_;}
private:
int maxPoints_;
float maxRange_;
Transform localTransform_;
};
}
#endif /* CORELIB_INCLUDE_RTABMAP_CORE_LASERSCANINFO_H_ */

View File

@@ -1,5 +1,5 @@
/* /*
Copyright (c) 2010-2014, Mathieu Labbe - IntRoLab - Universite de Sherbrooke Copyright (c) 2010-2016, Mathieu Labbe - IntRoLab - Universite de Sherbrooke
All rights reserved. All rights reserved.
Redistribution and use in source and binary forms, with or without Redistribution and use in source and binary forms, with or without
@@ -76,11 +76,7 @@ public:
void setTo(int to) {to_ = to;} void setTo(int to) {to_ = to;}
void setTransform(const Transform & transform) {transform_ = transform;} void setTransform(const Transform & transform) {transform_ = transform;}
void setType(Type type) {type_ = type;} void setType(Type type) {type_ = type;}
void setInfMatrix(const cv::Mat & infMatrix);
void setVariance(double rotVariance, double transVariance);
void setUserDataRaw(const cv::Mat & userDataRaw); // only set raw
void setUserData(const cv::Mat & userData); // detect automatically if raw or compressed. If raw, the data is compressed too.
const cv::Mat & userDataRaw() const {return _userDataRaw;} const cv::Mat & userDataRaw() const {return _userDataRaw;}
const cv::Mat & userDataCompressed() const {return _userDataCompressed;} const cv::Mat & userDataCompressed() const {return _userDataCompressed;}
void uncompressUserData(); void uncompressUserData();
@@ -89,6 +85,10 @@ public:
Link merge(const Link & link, Type outputType) const; Link merge(const Link & link, Type outputType) const;
Link inverse() const; Link inverse() const;
private:
void setInfMatrix(const cv::Mat & infMatrix);
void setVariance(double rotVariance, double transVariance);
private: private:
int from_; int from_;
int to_; int to_;

View File

@@ -1,5 +1,5 @@
/* /*
Copyright (c) 2010-2014, Mathieu Labbe - IntRoLab - Universite de Sherbrooke Copyright (c) 2010-2016, Mathieu Labbe - IntRoLab - Universite de Sherbrooke
All rights reserved. All rights reserved.
Redistribution and use in source and binary forms, with or without Redistribution and use in source and binary forms, with or without
@@ -55,6 +55,7 @@ class Registration;
class RegistrationInfo; class RegistrationInfo;
class RegistrationIcp; class RegistrationIcp;
class Stereo; class Stereo;
class OccupancyGrid;
class RTABMAP_EXP Memory class RTABMAP_EXP Memory
{ {
@@ -79,7 +80,7 @@ public:
bool dbOverwritten = false, bool dbOverwritten = false,
const ParametersMap & parameters = ParametersMap(), const ParametersMap & parameters = ParametersMap(),
bool postInitClosingEvents = false); bool postInitClosingEvents = false);
void close(bool databaseSaved = true, bool postInitClosingEvents = false); void close(bool databaseSaved = true, bool postInitClosingEvents = false, const std::string & ouputDatabasePath = "");
std::map<int, float> computeLikelihood(const Signature * signature, std::map<int, float> computeLikelihood(const Signature * signature,
const std::list<int> & ids); const std::list<int> & ids);
int incrementMapId(std::map<int, int> * reducedIds = 0); int incrementMapId(std::map<int, int> * reducedIds = 0);
@@ -89,11 +90,11 @@ public:
std::set<int> reactivateSignatures(const std::list<int> & ids, unsigned int maxLoaded, double & timeDbAccess); std::set<int> reactivateSignatures(const std::list<int> & ids, unsigned int maxLoaded, double & timeDbAccess);
int cleanup(); int cleanup();
void saveStatistics(const Statistics & statistics);
void emptyTrash(); void emptyTrash();
void joinTrashThread(); void joinTrashThread();
bool addLink(const Link & link, bool addInDatabase = false); bool addLink(const Link & link, bool addInDatabase = false);
void updateLink(int fromId, int toId, const Transform & transform, float rotVariance, float transVariance); void updateLink(const Link & link, bool updateInDatabase = false);
void updateLink(int fromId, int toId, const Transform & transform, const cv::Mat & covariance);
void removeAllVirtualLinks(); void removeAllVirtualLinks();
void removeVirtualLinks(int signatureId); void removeVirtualLinks(int signatureId);
std::map<int, int> getNeighborsId( std::map<int, int> getNeighborsId(
@@ -132,6 +133,13 @@ public:
int getSignatureIdByLabel(const std::string & label, bool lookInDatabase = true) const; int getSignatureIdByLabel(const std::string & label, bool lookInDatabase = true) const;
bool labelSignature(int id, const std::string & label); bool labelSignature(int id, const std::string & label);
std::map<int, std::string> getAllLabels() const; std::map<int, std::string> getAllLabels() const;
/**
* Set user data. Detect automatically if raw or compressed. If raw, the data is
* compressed too. A matrix of type CV_8UC1 with 1 row is considered as compressed.
* If you have one dimension unsigned 8 bits raw data, make sure to transpose it
* (to have multiple rows instead of multiple columns) in order to be detected as
* not compressed.
*/
bool setUserData(int id, const cv::Mat & data); bool setUserData(int id, const cv::Mat & data);
int getDatabaseMemoryUsed() const; // in bytes int getDatabaseMemoryUsed() const; // in bytes
std::string getDatabaseVersion() const; std::string getDatabaseVersion() const;
@@ -155,7 +163,7 @@ public:
void getNodeCalibration(int nodeId, void getNodeCalibration(int nodeId,
std::vector<CameraModel> & models, std::vector<CameraModel> & models,
StereoCameraModel & stereoModel); StereoCameraModel & stereoModel);
SensorData getSignatureDataConst(int locationId) const; SensorData getSignatureDataConst(int locationId, bool images = true, bool scan = true, bool userData = true, bool occupancyGrid = true) const;
std::set<int> getAllSignatureIds() const; std::set<int> getAllSignatureIds() const;
bool memoryChanged() const {return _memoryChanged;} bool memoryChanged() const {return _memoryChanged;}
bool isIncremental() const {return _incrementalMemory;} bool isIncremental() const {return _incrementalMemory;}
@@ -185,8 +193,8 @@ public:
std::multimap<int, Link> & links, std::multimap<int, Link> & links,
bool lookInDatabase = false); bool lookInDatabase = false);
Transform computeTransform(Signature & fromS, Signature & toS, Transform guess, RegistrationInfo * info = 0) const; Transform computeTransform(Signature & fromS, Signature & toS, Transform guess, RegistrationInfo * info = 0, bool useKnownCorrespondencesIfPossible = false) const;
Transform computeTransform(int fromId, int toId, Transform guess, RegistrationInfo * info = 0); Transform computeTransform(int fromId, int toId, Transform guess, RegistrationInfo * info = 0, bool useKnownCorrespondencesIfPossible = false);
Transform computeIcpTransform(int fromId, int toId, Transform guess, RegistrationInfo * info = 0); Transform computeIcpTransform(int fromId, int toId, Transform guess, RegistrationInfo * info = 0);
Transform computeIcpTransformMulti( Transform computeIcpTransformMulti(
int newId, int newId,
@@ -198,6 +206,7 @@ private:
void preUpdate(); void preUpdate();
void addSignatureToStm(Signature * signature, const cv::Mat & covariance); void addSignatureToStm(Signature * signature, const cv::Mat & covariance);
void clear(); void clear();
void loadDataFromDb(bool postInitClosingEvents);
void moveToTrash(Signature * s, bool keepLinkedToGraph = true, std::list<int> * deletedWords = 0); void moveToTrash(Signature * s, bool keepLinkedToGraph = true, std::list<int> * deletedWords = 0);
void moveSignatureToWMFromSTM(int id, int * reducedTo = 0); void moveSignatureToWMFromSTM(int id, int * reducedTo = 0);
@@ -247,11 +256,13 @@ private:
int _imagePreDecimation; int _imagePreDecimation;
int _imagePostDecimation; int _imagePostDecimation;
float _laserScanDownsampleStepSize; float _laserScanDownsampleStepSize;
int _laserScanNormalK;
bool _reextractLoopClosureFeatures; bool _reextractLoopClosureFeatures;
float _rehearsalMaxDistance; float _rehearsalMaxDistance;
float _rehearsalMaxAngle; float _rehearsalMaxAngle;
bool _rehearsalWeightIgnoredWhileMoving; bool _rehearsalWeightIgnoredWhileMoving;
bool _useOdometryFeatures; bool _useOdometryFeatures;
bool _createOccupancyGrid;
int _idCount; int _idCount;
int _idMapCount; int _idMapCount;
@@ -274,6 +285,8 @@ private:
Registration * _registrationPipeline; Registration * _registrationPipeline;
RegistrationIcp * _registrationIcp; RegistrationIcp * _registrationIcp;
OccupancyGrid * _occupancy;
}; };
} // namespace rtabmap } // namespace rtabmap

View File

@@ -0,0 +1,120 @@
/*
Copyright (c) 2010-2016, Mathieu Labbe - IntRoLab - Universite de Sherbrooke
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
* Neither the name of the Universite de Sherbrooke nor the
names of its contributors may be used to endorse or promote products
derived from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef CORELIB_SRC_OCCUPANCYGRID_H_
#define CORELIB_SRC_OCCUPANCYGRID_H_
#include "rtabmap/core/RtabmapExp.h" // DLL export/import defines
#include <pcl/point_cloud.h>
#include <pcl/pcl_base.h>
#include <rtabmap/core/Parameters.h>
#include <rtabmap/core/Signature.h>
namespace rtabmap {
class RTABMAP_EXP OccupancyGrid
{
public:
OccupancyGrid(const ParametersMap & parameters = ParametersMap());
void parseParameters(const ParametersMap & parameters);
void setCellSize(float cellSize);
float getCellSize() const {return cellSize_;}
bool isGridFromDepth() const {return occupancyFromCloud_;}
template<typename PointT>
typename pcl::PointCloud<PointT>::Ptr segmentCloud(
const typename pcl::PointCloud<PointT>::Ptr & cloud,
const pcl::IndicesPtr & indices,
const Transform & pose,
const cv::Point3f & viewPoint,
pcl::IndicesPtr & groundIndices, // output cloud indices
pcl::IndicesPtr & obstaclesIndices, // output cloud indices
pcl::IndicesPtr * flatObstacles = 0) const; // output cloud indices
void createLocalMap(
const Signature & node,
cv::Mat & ground,
cv::Mat & obstacles,
cv::Point3f & viewPoint) const;
void clear();
void addToCache(
int nodeId,
const cv::Mat & ground,
const cv::Mat & obstacles);
void update(const std::map<int, Transform> & poses, float minMapSize = 0.0f, float footprintRadius = 0.0f);
const cv::Mat & getMap(float & xMin, float & yMin) const
{
xMin = xMin_;
yMin = yMin_;
return map_;
}
private:
ParametersMap parameters_;
int cloudDecimation_;
float cloudMaxDepth_;
float cloudMinDepth_;
std::vector<float> roiRatios_;
float footprintLength_;
float footprintWidth_;
float footprintHeight_;
int scanDecimation_;
float cellSize_;
bool occupancyFromCloud_;
bool projMapFrame_;
float maxObstacleHeight_;
int normalKSearch_;
float maxGroundAngle_;
float clusterRadius_;
int minClusterSize_;
bool flatObstaclesDetected_;
float minGroundHeight_;
float maxGroundHeight_;
bool normalsSegmentation_;
bool grid3D_;
bool groundIsObstacle_;
float noiseFilteringRadius_;
int noiseFilteringMinNeighbors_;
bool scan2dUnknownSpaceFilled_;
double scan2dMaxUnknownSpaceFilledRange_;
std::map<int, std::pair<cv::Mat, cv::Mat> > cache_;
cv::Mat map_;
cv::Mat mapInfo_;
std::map<int, std::pair<int, int> > cellCount_; //<node Id, cells>
float xMin_;
float yMin_;
std::map<int, Transform> addedNodes_;
};
}
#include <rtabmap/core/impl/OccupancyGrid.hpp>
#endif /* CORELIB_SRC_OCCUPANCYGRID_H_ */

View File

@@ -0,0 +1,104 @@
/*
Copyright (c) 2010-2016, Mathieu Labbe - IntRoLab - Universite de Sherbrooke
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
* Neither the name of the Universite de Sherbrooke nor the
names of its contributors may be used to endorse or promote products
derived from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef SRC_OCTOMAP_H_
#define SRC_OCTOMAP_H_
#include "rtabmap/core/RtabmapExp.h" // DLL export/import defines
#include <octomap/ColorOcTree.h>
#include <octomap/OcTreeKey.h>
#include <pcl/pcl_base.h>
#include <pcl/point_types.h>
#include <rtabmap/core/Transform.h>
#include <map>
#include <string>
namespace rtabmap {
class OcTreeNodeInfo
{
public:
OcTreeNodeInfo(int nodeRefId, const octomap::OcTreeKey & key, bool isObstacle) :
nodeRefId_(nodeRefId),
key_(key),
isObstacle_(isObstacle) {}
int nodeRefId_;
octomap::OcTreeKey key_;
bool isObstacle_;
};
class RTABMAP_EXP OctoMap {
public:
OctoMap(float voxelSize = 0.1f, float occupancyThr = 0.5f);
const std::map<int, Transform> & addedNodes() const {return addedNodes_;}
void addToCache(int nodeId,
pcl::PointCloud<pcl::PointXYZRGB>::Ptr & ground,
pcl::PointCloud<pcl::PointXYZRGB>::Ptr & obstacles,
const pcl::PointXYZ & viewPoint);
void addToCache(int nodeId,
const cv::Mat & ground,
const cv::Mat & obstacles,
const cv::Point3f & viewPoint);
void update(const std::map<int, Transform> & poses);
const octomap::ColorOcTree * octree() const {return octree_;}
pcl::PointCloud<pcl::PointXYZRGB>::Ptr createCloud(
unsigned int treeDepth = 0,
std::vector<int> * obstacleIndices = 0,
std::vector<int> * emptyIndices = 0) const;
cv::Mat createProjectionMap(
float & xMin,
float & yMin,
float & gridCellSize,
float minGridSize);
bool writeBinary(const std::string & path);
virtual ~OctoMap();
void clear();
private:
std::map<int, std::pair<cv::Mat, cv::Mat> > cache_;
std::map<int, std::pair<pcl::PointCloud<pcl::PointXYZRGB>::Ptr, pcl::PointCloud<pcl::PointXYZRGB>::Ptr> > cacheClouds_;
std::map<int, cv::Point3f> cacheViewPoints_;
octomap::ColorOcTree * octree_;
std::map<octomap::ColorOcTreeNode*, OcTreeNodeInfo> occupiedCells_;
std::map<int, Transform> addedNodes_;
octomap::KeyRay keyRay_;
bool hasColor_;
};
} /* namespace rtabmap */
#endif /* SRC_OCTOMAP_H_ */

View File

@@ -1,5 +1,5 @@
/* /*
Copyright (c) 2010-2014, Mathieu Labbe - IntRoLab - Universite de Sherbrooke Copyright (c) 2010-2016, Mathieu Labbe - IntRoLab - Universite de Sherbrooke
All rights reserved. All rights reserved.
Redistribution and use in source and binary forms, with or without Redistribution and use in source and binary forms, with or without
@@ -44,7 +44,7 @@ class RTABMAP_EXP Odometry
public: public:
enum Type { enum Type {
kTypeUndef = -1, kTypeUndef = -1,
kTypeLocalMap = 0, kTypeF2M = 0,
kTypeF2F = 1 kTypeF2F = 1
}; };
@@ -55,12 +55,15 @@ public:
public: public:
virtual ~Odometry(); virtual ~Odometry();
Transform process(SensorData & data, OdometryInfo * info = 0); Transform process(SensorData & data, OdometryInfo * info = 0);
Transform process(SensorData & data, const Transform & guess, OdometryInfo * info = 0);
virtual void reset(const Transform & initialPose = Transform::getIdentity()); virtual void reset(const Transform & initialPose = Transform::getIdentity());
virtual Odometry::Type getType() = 0;
//getters //getters
const Transform & getPose() const {return _pose;} const Transform & getPose() const {return _pose;}
bool isInfoDataFilled() const {return _fillInfoData;} bool isInfoDataFilled() const {return _fillInfoData;}
const Transform & previousVelocityTransform() const {return previousVelocityTransform_;} const Transform & previousVelocityTransform() const {return previousVelocityTransform_;}
double previousStamp() const {return previousStamp_;}
private: private:
virtual Transform computeTransform(SensorData & data, const Transform & guess = Transform(), OdometryInfo * info = 0) = 0; virtual Transform computeTransform(SensorData & data, const Transform & guess = Transform(), OdometryInfo * info = 0) = 0;
@@ -84,6 +87,7 @@ private:
float _kalmanProcessNoise; float _kalmanProcessNoise;
float _kalmanMeasurementNoise; float _kalmanMeasurementNoise;
int _imageDecimation; int _imageDecimation;
bool _alignWithGround;
Transform _pose; Transform _pose;
int _resetCurrentCount; int _resetCurrentCount;
double previousStamp_; double previousStamp_;

View File

@@ -1,5 +1,5 @@
/* /*
Copyright (c) 2010-2014, Mathieu Labbe - IntRoLab - Universite de Sherbrooke Copyright (c) 2010-2016, Mathieu Labbe - IntRoLab - Universite de Sherbrooke
All rights reserved. All rights reserved.
Redistribution and use in source and binary forms, with or without Redistribution and use in source and binary forms, with or without

View File

@@ -1,5 +1,5 @@
/* /*
Copyright (c) 2010-2014, Mathieu Labbe - IntRoLab - Universite de Sherbrooke Copyright (c) 2010-2016, Mathieu Labbe - IntRoLab - Universite de Sherbrooke
All rights reserved. All rights reserved.
Redistribution and use in source and binary forms, with or without Redistribution and use in source and binary forms, with or without
@@ -45,12 +45,15 @@ public:
const Signature & getRefFrame() const {return refFrame_;} const Signature & getRefFrame() const {return refFrame_;}
virtual Odometry::Type getType() {return Odometry::kTypeF2F;}
private: private:
virtual Transform computeTransform(SensorData & image, const Transform & guess = Transform(), OdometryInfo * info = 0); virtual Transform computeTransform(SensorData & image, const Transform & guess = Transform(), OdometryInfo * info = 0);
private: private:
//Parameters: //Parameters:
float keyFrameThr_; float keyFrameThr_;
int visKeyFrameThr_;
float scanKeyFrameThr_; float scanKeyFrameThr_;
Registration * registrationPipeline_; Registration * registrationPipeline_;

View File

@@ -1,5 +1,5 @@
/* /*
Copyright (c) 2010-2014, Mathieu Labbe - IntRoLab - Universite de Sherbrooke Copyright (c) 2010-2016, Mathieu Labbe - IntRoLab - Universite de Sherbrooke
All rights reserved. All rights reserved.
Redistribution and use in source and binary forms, with or without Redistribution and use in source and binary forms, with or without
@@ -31,11 +31,14 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include <rtabmap/core/Odometry.h> #include <rtabmap/core/Odometry.h>
#include <pcl/point_cloud.h> #include <pcl/point_cloud.h>
#include <pcl/point_types.h> #include <pcl/point_types.h>
#include <pcl/pcl_base.h>
#include <rtabmap/core/Link.h>
namespace rtabmap { namespace rtabmap {
class Signature; class Signature;
class Registration; class Registration;
class Optimizer;
class RTABMAP_EXP OdometryF2M : public Odometry class RTABMAP_EXP OdometryF2M : public Odometry
{ {
@@ -47,6 +50,8 @@ public:
const Signature & getMap() const {return *map_;} const Signature & getMap() const {return *map_;}
const Signature & getLastFrame() const {return *lastFrame_;} const Signature & getLastFrame() const {return *lastFrame_;}
virtual Odometry::Type getType() {return Odometry::kTypeF2M;}
private: private:
virtual Transform computeTransform(SensorData & data, const Transform & guess = Transform(), OdometryInfo * info = 0); virtual Transform computeTransform(SensorData & data, const Transform & guess = Transform(), OdometryInfo * info = 0);
@@ -54,16 +59,25 @@ private:
//Parameters //Parameters
int maximumMapSize_; int maximumMapSize_;
float keyFrameThr_; float keyFrameThr_;
int visKeyFrameThr_;
int maxNewFeatures_; int maxNewFeatures_;
float scanKeyFrameThr_; float scanKeyFrameThr_;
int scanMaximumMapSize_; int scanMaximumMapSize_;
float scanSubstractRadius_; float scanSubtractRadius_;
std::string fixedMapPath_; int bundleAdjustment_;
int bundleMaxFrames_;
Registration * regPipeline_; Registration * regPipeline_;
Signature * map_; Signature * map_;
Signature * lastFrame_; Signature * lastFrame_;
std::map<int, pcl::PointCloud<pcl::PointNormal>::Ptr > scansBuffer_; std::vector<std::pair<pcl::PointCloud<pcl::PointNormal>::Ptr, pcl::IndicesPtr> > scansBuffer_;
std::map<int, std::map<int, cv::Point3f> > bundleWordReferences_; //<WordId, <FrameId, pt2D+depth>>
std::map<int, Transform> bundlePoses_;
std::multimap<int, Link> bundleLinks_;
std::map<int, CameraModel> bundleModels_;
std::map<int, int> bundlePoseReferences_;
Optimizer * sba_;
}; };
} }

View File

@@ -1,5 +1,5 @@
/* /*
Copyright (c) 2010-2014, Mathieu Labbe - IntRoLab - Universite de Sherbrooke Copyright (c) 2010-2016, Mathieu Labbe - IntRoLab - Universite de Sherbrooke
All rights reserved. All rights reserved.
Redistribution and use in source and binary forms, with or without Redistribution and use in source and binary forms, with or without
@@ -42,10 +42,16 @@ public:
matches(0), matches(0),
inliers(0), inliers(0),
icpInliersRatio(0.0f), icpInliersRatio(0.0f),
variance(0.0f), varianceLin(0.0f),
varianceAng(0.0f),
features(0), features(0),
localMapSize(0), localMapSize(0),
localScanMapSize(0), localScanMapSize(0),
localKeyFrames(0),
localBundleOutliers(0),
localBundleConstraints(0),
localBundleTime(0),
keyFrameAdded(false),
timeEstimation(0.0f), timeEstimation(0.0f),
timeParticleFiltering(0.0f), timeParticleFiltering(0.0f),
stamp(0), stamp(0),
@@ -61,10 +67,16 @@ public:
output.matches = matches; output.matches = matches;
output.inliers = inliers; output.inliers = inliers;
output.icpInliersRatio = icpInliersRatio; output.icpInliersRatio = icpInliersRatio;
output.variance = variance; output.varianceLin = varianceLin;
output.varianceAng = varianceAng;
output.features = features; output.features = features;
output.localMapSize = localMapSize; output.localMapSize = localMapSize;
output.localScanMapSize = localScanMapSize; output.localScanMapSize = localScanMapSize;
output.localKeyFrames = localKeyFrames;
output.localBundleOutliers = localBundleOutliers;
output.localBundleConstraints = localBundleConstraints;
output.localBundleTime = localBundleTime;
output.keyFrameAdded = keyFrameAdded;
output.timeEstimation = timeEstimation; output.timeEstimation = timeEstimation;
output.timeParticleFiltering = timeParticleFiltering; output.timeParticleFiltering = timeParticleFiltering;
output.stamp = stamp; output.stamp = stamp;
@@ -72,6 +84,7 @@ public:
output.transformFiltered = transformFiltered; output.transformFiltered = transformFiltered;
output.transformGroundTruth = transformGroundTruth; output.transformGroundTruth = transformGroundTruth;
output.distanceTravelled = distanceTravelled; output.distanceTravelled = distanceTravelled;
output.type = type;
return output; return output;
} }
@@ -79,10 +92,16 @@ public:
int matches; int matches;
int inliers; int inliers;
float icpInliersRatio; float icpInliersRatio;
float variance; float varianceLin;
float varianceAng;
int features; int features;
int localMapSize; int localMapSize;
int localScanMapSize; int localScanMapSize;
int localKeyFrames;
int localBundleOutliers;
int localBundleConstraints;
float localBundleTime;
bool keyFrameAdded;
float timeEstimation; float timeEstimation;
float timeParticleFiltering; float timeParticleFiltering;
double stamp; double stamp;

View File

@@ -1,5 +1,5 @@
/* /*
Copyright (c) 2010-2014, Mathieu Labbe - IntRoLab - Universite de Sherbrooke Copyright (c) 2010-2016, Mathieu Labbe - IntRoLab - Universite de Sherbrooke
All rights reserved. All rights reserved.
Redistribution and use in source and binary forms, with or without Redistribution and use in source and binary forms, with or without

View File

@@ -1,5 +1,5 @@
/* /*
Copyright (c) 2010-2014, Mathieu Labbe - IntRoLab - Universite de Sherbrooke Copyright (c) 2010-2016, Mathieu Labbe - IntRoLab - Universite de Sherbrooke
All rights reserved. All rights reserved.
Redistribution and use in source and binary forms, with or without Redistribution and use in source and binary forms, with or without
@@ -48,12 +48,13 @@ protected:
virtual void handleEvent(UEvent * event); virtual void handleEvent(UEvent * event);
private: private:
void mainLoopKill(); virtual void mainLoopBegin();
virtual void mainLoopKill();
//============================================================ //============================================================
// MAIN LOOP // MAIN LOOP
//============================================================ //============================================================
void mainLoop(); virtual void mainLoop();
void addData(const SensorData & data); void addData(const SensorData & data);
bool getData(SensorData & data); bool getData(SensorData & data);

View File

@@ -1,5 +1,5 @@
/* /*
Copyright (c) 2010-2014, Mathieu Labbe - IntRoLab - Universite de Sherbrooke Copyright (c) 2010-2016, Mathieu Labbe - IntRoLab - Universite de Sherbrooke
All rights reserved. All rights reserved.
Redistribution and use in source and binary forms, with or without Redistribution and use in source and binary forms, with or without
@@ -83,6 +83,8 @@ public:
void setEpsilon(double epsilon) {epsilon_ = epsilon;} void setEpsilon(double epsilon) {epsilon_ = epsilon;}
void setRobust(bool enabled) {robust_ = enabled;} void setRobust(bool enabled) {robust_ = enabled;}
virtual void parseParameters(const ParametersMap & parameters);
// inherited classes should implement one of these methods // inherited classes should implement one of these methods
virtual std::map<int, Transform> optimize( virtual std::map<int, Transform> optimize(
int rootId, int rootId,
@@ -92,24 +94,38 @@ public:
double * finalError = 0, double * finalError = 0,
int * iterationsDone = 0); int * iterationsDone = 0);
virtual std::map<int, Transform> optimizeBA( virtual std::map<int, Transform> optimizeBA(
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
std::map<int, cv::Point3f> & points3DMap,
const std::map<int, std::map<int, cv::Point3f> > & wordReferences, // <ID words, IDs frames + keypoint(x,y,depth)>
std::set<int> * outliers = 0);
std::map<int, Transform> optimizeBA(
int rootId, int rootId,
const std::map<int, Transform> & poses, const std::map<int, Transform> & poses,
const std::multimap<int, Link> & links, const std::multimap<int, Link> & links,
const std::map<int, Signature> & signatures); const std::map<int, Signature> & signatures);
virtual void parseParameters(const ParametersMap & parameters); Transform optimizeBA(
const Link & link,
const CameraModel & model,
std::map<int, cv::Point3f> & points3DMap,
const std::map<int, std::map<int, cv::Point3f> > & wordReferences,
std::set<int> * outliers = 0);
void computeBACorrespondences( void computeBACorrespondences(
const std::map<int, Transform> & poses, const std::map<int, Transform> & poses,
const std::multimap<int, Link> & links, const std::multimap<int, Link> & links,
const std::map<int, Signature> & signatures, const std::map<int, Signature> & signatures,
std::map<int, cv::Point3f> & points3DMap, std::map<int, cv::Point3f> & points3DMap,
std::map<int, std::map<int, cv::Point2f> > & wordReferences); // <ID words, IDs frames + keypoint> std::map<int, std::map<int, cv::Point3f> > & wordReferences); // <ID words, IDs frames + keypoint/depth>
protected: protected:
Optimizer( Optimizer(
int iterations = Parameters::defaultOptimizerIterations(), int iterations = Parameters::defaultOptimizerIterations(),
bool slam2d = Parameters::defaultOptimizerSlam2D(), bool slam2d = Parameters::defaultRegForce3DoF(),
bool covarianceIgnored = Parameters::defaultOptimizerVarianceIgnored(), bool covarianceIgnored = Parameters::defaultOptimizerVarianceIgnored(),
double epsilon = Parameters::defaultOptimizerEpsilon(), double epsilon = Parameters::defaultOptimizerEpsilon(),
bool robust = Parameters::defaultOptimizerRobust()); bool robust = Parameters::defaultOptimizerRobust());

View File

@@ -1,5 +1,5 @@
/* /*
Copyright (c) 2010-2014, Mathieu Labbe - IntRoLab - Universite de Sherbrooke Copyright (c) 2010-2016, Mathieu Labbe - IntRoLab - Universite de Sherbrooke
All rights reserved. All rights reserved.
Redistribution and use in source and binary forms, with or without Redistribution and use in source and binary forms, with or without
@@ -42,7 +42,7 @@ public:
public: public:
OptimizerCVSBA( OptimizerCVSBA(
int iterations = Parameters::defaultOptimizerIterations(), int iterations = Parameters::defaultOptimizerIterations(),
bool slam2d = Parameters::defaultOptimizerSlam2D(), bool slam2d = Parameters::defaultRegForce3DoF(),
bool covarianceIgnored = Parameters::defaultOptimizerVarianceIgnored()) : bool covarianceIgnored = Parameters::defaultOptimizerVarianceIgnored()) :
Optimizer(iterations, slam2d, covarianceIgnored) {} Optimizer(iterations, slam2d, covarianceIgnored) {}
OptimizerCVSBA(const ParametersMap & parameters) : OptimizerCVSBA(const ParametersMap & parameters) :
@@ -55,7 +55,10 @@ public:
int rootId, int rootId,
const std::map<int, Transform> & poses, const std::map<int, Transform> & poses,
const std::multimap<int, Link> & links, const std::multimap<int, Link> & links,
const std::map<int, Signature> & signatures); const std::map<int, CameraModel> & models,
std::map<int, cv::Point3f> & points3DMap,
const std::map<int, std::map<int, cv::Point3f> > & wordReferences, // <ID words, IDs frames + keypoint(x,y,depth)>
std::set<int> * outliers = 0);
}; };
} /* namespace rtabmap */ } /* namespace rtabmap */

View File

@@ -1,5 +1,5 @@
/* /*
Copyright (c) 2010-2014, Mathieu Labbe - IntRoLab - Universite de Sherbrooke Copyright (c) 2010-2016, Mathieu Labbe - IntRoLab - Universite de Sherbrooke
All rights reserved. All rights reserved.
Redistribution and use in source and binary forms, with or without Redistribution and use in source and binary forms, with or without
@@ -51,7 +51,9 @@ public:
Optimizer(parameters), Optimizer(parameters),
solver_(Parameters::defaultg2oSolver()), solver_(Parameters::defaultg2oSolver()),
optimizer_(Parameters::defaultg2oOptimizer()), optimizer_(Parameters::defaultg2oOptimizer()),
pixelVariance_(Parameters::defaultg2oPixelVariance()) pixelVariance_(Parameters::defaultg2oPixelVariance()),
robustKernelDelta_(Parameters::defaultg2oRobustKernelDelta()),
baseline_(Parameters::defaultg2oBaseline())
{ {
parseParameters(parameters); parseParameters(parameters);
} }
@@ -73,12 +75,17 @@ public:
int rootId, int rootId,
const std::map<int, Transform> & poses, const std::map<int, Transform> & poses,
const std::multimap<int, Link> & links, const std::multimap<int, Link> & links,
const std::map<int, Signature> & signatures); const std::map<int, CameraModel> & models, // in case of stereo, Tx should be set
std::map<int, cv::Point3f> & points3DMap,
const std::map<int, std::map<int, cv::Point3f> > & wordReferences, // <ID words, IDs frames + keypoint(x,y,depth)>
std::set<int> * outliers = 0);
private: private:
int solver_; int solver_;
int optimizer_; int optimizer_;
double pixelVariance_; double pixelVariance_;
double robustKernelDelta_;
double baseline_;
}; };
} /* namespace rtabmap */ } /* namespace rtabmap */

View File

@@ -1,5 +1,5 @@
/* /*
Copyright (c) 2010-2014, Mathieu Labbe - IntRoLab - Universite de Sherbrooke Copyright (c) 2010-2016, Mathieu Labbe - IntRoLab - Universite de Sherbrooke
All rights reserved. All rights reserved.
Redistribution and use in source and binary forms, with or without Redistribution and use in source and binary forms, with or without
@@ -42,7 +42,7 @@ public:
public: public:
OptimizerGTSAM( OptimizerGTSAM(
int iterations = Parameters::defaultOptimizerIterations(), int iterations = Parameters::defaultOptimizerIterations(),
bool slam2d = Parameters::defaultOptimizerSlam2D(), bool slam2d = Parameters::defaultRegForce3DoF(),
bool covarianceIgnored = Parameters::defaultOptimizerVarianceIgnored(), bool covarianceIgnored = Parameters::defaultOptimizerVarianceIgnored(),
double epsilon = Parameters::defaultOptimizerEpsilon(), double epsilon = Parameters::defaultOptimizerEpsilon(),
bool robust = Parameters::defaultOptimizerRobust()) : bool robust = Parameters::defaultOptimizerRobust()) :

View File

@@ -1,5 +1,5 @@
/* /*
Copyright (c) 2010-2014, Mathieu Labbe - IntRoLab - Universite de Sherbrooke Copyright (c) 2010-2016, Mathieu Labbe - IntRoLab - Universite de Sherbrooke
All rights reserved. All rights reserved.
Redistribution and use in source and binary forms, with or without Redistribution and use in source and binary forms, with or without
@@ -52,7 +52,7 @@ public:
public: public:
OptimizerTORO( OptimizerTORO(
int iterations = Parameters::defaultOptimizerIterations(), int iterations = Parameters::defaultOptimizerIterations(),
bool slam2d = Parameters::defaultOptimizerSlam2D(), bool slam2d = Parameters::defaultRegForce3DoF(),
bool covarianceIgnored = Parameters::defaultOptimizerVarianceIgnored(), bool covarianceIgnored = Parameters::defaultOptimizerVarianceIgnored(),
double epsilon = Parameters::defaultOptimizerEpsilon()) : double epsilon = Parameters::defaultOptimizerEpsilon()) :
Optimizer(iterations, slam2d, covarianceIgnored, epsilon) {} Optimizer(iterations, slam2d, covarianceIgnored, epsilon) {}

View File

@@ -1,5 +1,5 @@
/* /*
Copyright (c) 2010-2014, Mathieu Labbe - IntRoLab - Universite de Sherbrooke Copyright (c) 2010-2016, Mathieu Labbe - IntRoLab - Universite de Sherbrooke
All rights reserved. All rights reserved.
Redistribution and use in source and binary forms, with or without Redistribution and use in source and binary forms, with or without

View File

@@ -1,5 +1,5 @@
/* /*
Copyright (c) 2010-2014, Mathieu Labbe - IntRoLab - Universite de Sherbrooke Copyright (c) 2010-2016, Mathieu Labbe - IntRoLab - Universite de Sherbrooke
All rights reserved. All rights reserved.
Redistribution and use in source and binary forms, with or without Redistribution and use in source and binary forms, with or without
@@ -31,6 +31,7 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
// default parameters // default parameters
#include "rtabmap/core/RtabmapExp.h" // DLL export/import defines #include "rtabmap/core/RtabmapExp.h" // DLL export/import defines
#include "rtabmap/core/Version.h" // DLL export/import defines #include "rtabmap/core/Version.h" // DLL export/import defines
#include <rtabmap/utilite/UConversion.h>
#include <string> #include <string>
#include <map> #include <map>
@@ -172,11 +173,11 @@ class RTABMAP_EXP Parameters
RTABMAP_PARAM(Rtabmap, PublishLastSignature, bool, true, "Publishing last signature."); RTABMAP_PARAM(Rtabmap, PublishLastSignature, bool, true, "Publishing last signature.");
RTABMAP_PARAM(Rtabmap, PublishPdf, bool, true, "Publishing pdf."); RTABMAP_PARAM(Rtabmap, PublishPdf, bool, true, "Publishing pdf.");
RTABMAP_PARAM(Rtabmap, PublishLikelihood, bool, true, "Publishing likelihood."); RTABMAP_PARAM(Rtabmap, PublishLikelihood, bool, true, "Publishing likelihood.");
RTABMAP_PARAM(Rtabmap, TimeThr, float, 0.0, "Maximum time allowed for the detector (ms) (0 means infinity)."); RTABMAP_PARAM(Rtabmap, TimeThr, float, 0, "Maximum time allowed for the detector (ms) (0 means infinity).");
RTABMAP_PARAM(Rtabmap, MemoryThr, int, 0, "Maximum signatures in the Working Memory (ms) (0 means infinity)."); RTABMAP_PARAM(Rtabmap, MemoryThr, int, 0, "Maximum signatures in the Working Memory (ms) (0 means infinity).");
RTABMAP_PARAM(Rtabmap, DetectionRate, float, 1.0, "Detection rate. RTAB-Map will filter input images to satisfy this rate."); RTABMAP_PARAM(Rtabmap, DetectionRate, float, 1, "Detection rate. RTAB-Map will filter input images to satisfy this rate.");
RTABMAP_PARAM(Rtabmap, ImageBufferSize, unsigned int, 1, "Data buffer size (0 min inf)."); RTABMAP_PARAM(Rtabmap, ImageBufferSize, unsigned int, 1, "Data buffer size (0 min inf).");
RTABMAP_PARAM(Rtabmap, CreateIntermediateNodes, bool, false, "Create intermediate nodes between loop closure detection. Only used when Rtabmap/DetectionRate>0."); RTABMAP_PARAM(Rtabmap, CreateIntermediateNodes, bool, false, uFormat("Create intermediate nodes between loop closure detection. Only used when %s>0.", kRtabmapDetectionRate().c_str()));
RTABMAP_PARAM_STR(Rtabmap, WorkingDirectory, "", "Working directory."); RTABMAP_PARAM_STR(Rtabmap, WorkingDirectory, "", "Working directory.");
RTABMAP_PARAM(Rtabmap, MaxRetrieved, unsigned int, 2, "Maximum locations retrieved at the same time from LTM."); RTABMAP_PARAM(Rtabmap, MaxRetrieved, unsigned int, 2, "Maximum locations retrieved at the same time from LTM.");
RTABMAP_PARAM(Rtabmap, StatisticLogsBufferedInRAM, bool, true, "Statistic logs buffered in RAM instead of written to hard drive after each iteration."); RTABMAP_PARAM(Rtabmap, StatisticLogsBufferedInRAM, bool, true, "Statistic logs buffered in RAM instead of written to hard drive after each iteration.");
@@ -186,7 +187,7 @@ class RTABMAP_EXP Parameters
// Hypotheses selection // Hypotheses selection
RTABMAP_PARAM(Rtabmap, LoopThr, float, 0.11, "Loop closing threshold."); RTABMAP_PARAM(Rtabmap, LoopThr, float, 0.11, "Loop closing threshold.");
RTABMAP_PARAM(Rtabmap, LoopRatio, float, 0.0, "The loop closure hypothesis must be over LoopRatio x lastHypothesisValue."); RTABMAP_PARAM(Rtabmap, LoopRatio, float, 0, "The loop closure hypothesis must be over LoopRatio x lastHypothesisValue.");
// Memory // Memory
RTABMAP_PARAM(Mem, RehearsalSimilarity, float, 0.6, "Rehearsal similarity."); RTABMAP_PARAM(Mem, RehearsalSimilarity, float, 0.6, "Rehearsal similarity.");
@@ -194,7 +195,7 @@ class RTABMAP_EXP Parameters
RTABMAP_PARAM(Mem, BinDataKept, bool, true, "Keep binary data in db."); RTABMAP_PARAM(Mem, BinDataKept, bool, true, "Keep binary data in db.");
RTABMAP_PARAM(Mem, RawDescriptorsKept, bool, true, "Raw descriptors kept in memory."); RTABMAP_PARAM(Mem, RawDescriptorsKept, bool, true, "Raw descriptors kept in memory.");
RTABMAP_PARAM(Mem, 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 labelled as \"map#\" where # is the map ID.");
RTABMAP_PARAM(Mem, SaveDepth16Format, bool, true, "Save depth image into 16 bits format to reduce memory used. Warning: values over ~65 meters are ignored (maximum 65535 millimeters)."); RTABMAP_PARAM(Mem, SaveDepth16Format, bool, false, "Save depth image into 16 bits format to reduce memory used. Warning: values over ~65 meters are ignored (maximum 65535 millimeters).");
RTABMAP_PARAM(Mem, NotLinkedNodesKept, bool, true, "Keep not linked nodes in db (rehearsed nodes and deleted nodes)."); RTABMAP_PARAM(Mem, NotLinkedNodesKept, bool, true, "Keep not linked nodes in db (rehearsed nodes and deleted nodes).");
RTABMAP_PARAM(Mem, STMSize, unsigned int, 10, "Short-term memory size."); RTABMAP_PARAM(Mem, STMSize, unsigned int, 10, "Short-term memory size.");
RTABMAP_PARAM(Mem, IncrementalMemory, bool, true, "SLAM mode, otherwise it is Localization mode."); RTABMAP_PARAM(Mem, IncrementalMemory, bool, true, "SLAM mode, otherwise it is Localization mode.");
@@ -206,17 +207,18 @@ class RTABMAP_EXP Parameters
RTABMAP_PARAM(Mem, GenerateIds, bool, true, "True=Generate location IDs, False=use input image IDs."); RTABMAP_PARAM(Mem, GenerateIds, bool, true, "True=Generate location IDs, False=use input image IDs.");
RTABMAP_PARAM(Mem, BadSignaturesIgnored, bool, false, "Bad signatures are ignored."); RTABMAP_PARAM(Mem, BadSignaturesIgnored, bool, false, "Bad signatures are ignored.");
RTABMAP_PARAM(Mem, InitWMWithAllNodes, bool, false, "Initialize the Working Memory with all nodes in Long-Term Memory. When false, it is initialized with nodes of the previous session."); RTABMAP_PARAM(Mem, InitWMWithAllNodes, bool, false, "Initialize the Working Memory with all nodes in Long-Term Memory. When false, it is initialized with nodes of the previous session.");
RTABMAP_PARAM(Mem, ImagePreDecimation, int, 1, "Image decimation (>=1) before features extraction."); RTABMAP_PARAM(Mem, ImagePreDecimation, int, 1, "Image decimation (>=1) before features extraction. Negative decimation is done from RGB size instead of depth size (if depth is smaller than RGB, it may be interpolated depending of the decimation value).");
RTABMAP_PARAM(Mem, ImagePostDecimation, int, 1, "Image decimation (>=1) of saved data in created signatures (after features extraction). Decimation is done from the original image."); RTABMAP_PARAM(Mem, ImagePostDecimation, int, 1, "Image decimation (>=1) of saved data in created signatures (after features extraction). Decimation is done from the original image. Negative decimation is done from RGB size instead of depth size (if depth is smaller than RGB, it may be interpolated depending of the decimation value).");
RTABMAP_PARAM(Mem, LaserScanDownsampleStepSize, int, 1, "If > 1, downsample the laser scans when creating a signature."); RTABMAP_PARAM(Mem, LaserScanDownsampleStepSize, int, 1, "If > 1, downsample the laser scans when creating a signature.");
RTABMAP_PARAM(Mem, UseOdomFeatures, bool, false, "Use odometry features."); RTABMAP_PARAM(Mem, LaserScanNormalK, int, 0, "If > 0 and laser scans are 3D without normals, normals will be computed with K search neighbors when creating a signature.");
RTABMAP_PARAM(Mem, UseOdomFeatures, bool, false, "Use odometry features.");
// KeypointMemory (Keypoint-based) // KeypointMemory (Keypoint-based)
RTABMAP_PARAM(Kp, NNStrategy, int, 1, "kNNFlannNaive=0, kNNFlannKdTree=1, kNNFlannLSH=2, kNNBruteForce=3, kNNBruteForceGPU=4"); RTABMAP_PARAM(Kp, NNStrategy, int, 1, "kNNFlannNaive=0, kNNFlannKdTree=1, kNNFlannLSH=2, kNNBruteForce=3, kNNBruteForceGPU=4");
RTABMAP_PARAM(Kp, IncrementalDictionary, bool, true, ""); RTABMAP_PARAM(Kp, IncrementalDictionary, bool, true, "");
RTABMAP_PARAM(Kp, IncrementalFlann, bool, true, "When using FLANN based strategy, add/remove points to its index without always rebuilding the index (the index is built only when the dictionary doubles in size)."); RTABMAP_PARAM(Kp, IncrementalFlann, bool, true, "When using FLANN based strategy, add/remove points to its index without always rebuilding the index (the index is built only when the dictionary doubles in size).");
RTABMAP_PARAM(Kp, MaxDepth, float, 0.0, "Filter extracted keypoints by depth (0=inf)."); RTABMAP_PARAM(Kp, MaxDepth, float, 0, "Filter extracted keypoints by depth (0=inf).");
RTABMAP_PARAM(Kp, MinDepth, float, 0.0, "Filter extracted keypoints by depth."); RTABMAP_PARAM(Kp, MinDepth, float, 0, "Filter extracted keypoints by depth.");
RTABMAP_PARAM(Kp, MaxFeatures, int, 400, "Maximum features extracted from the images (0 means not bounded, <0 means no extraction)."); RTABMAP_PARAM(Kp, MaxFeatures, int, 400, "Maximum features extracted from the images (0 means not bounded, <0 means no extraction).");
RTABMAP_PARAM(Kp, BadSignRatio, float, 0.5, "Bad signature ratio (less than Ratio x AverageWordsPerImage = bad)."); RTABMAP_PARAM(Kp, BadSignRatio, float, 0.5, "Bad signature ratio (less than Ratio x AverageWordsPerImage = bad).");
RTABMAP_PARAM(Kp, NndrRatio, float, 0.8, "NNDR ratio (A matching pair is detected, if its distance is closer than X times the distance of the second nearest neighbor.)"); RTABMAP_PARAM(Kp, NndrRatio, float, 0.8, "NNDR ratio (A matching pair is detected, if its distance is closer than X times the distance of the second nearest neighbor.)");
@@ -243,7 +245,7 @@ class RTABMAP_EXP Parameters
// Keypoints descriptors/detectors // Keypoints descriptors/detectors
RTABMAP_PARAM(SURF, Extended, bool, false, "Extended descriptor flag (true - use extended 128-element descriptors; false - use 64-element descriptors)."); RTABMAP_PARAM(SURF, Extended, bool, false, "Extended descriptor flag (true - use extended 128-element descriptors; false - use 64-element descriptors).");
RTABMAP_PARAM(SURF, HessianThreshold, float, 500.0, "Threshold for hessian keypoint detector used in SURF."); RTABMAP_PARAM(SURF, HessianThreshold, float, 500, "Threshold for hessian keypoint detector used in SURF.");
RTABMAP_PARAM(SURF, Octaves, int, 4, "Number of pyramid octaves the keypoint detector will use."); RTABMAP_PARAM(SURF, Octaves, int, 4, "Number of pyramid octaves the keypoint detector will use.");
RTABMAP_PARAM(SURF, OctaveLayers, int, 2, "Number of octave layers within each octave."); RTABMAP_PARAM(SURF, OctaveLayers, int, 2, "Number of octave layers within each octave.");
RTABMAP_PARAM(SURF, Upright, bool, false, "Up-right or rotated features flag (true - do not compute orientation of features; false - compute orientation)."); RTABMAP_PARAM(SURF, Upright, bool, false, "Up-right or rotated features flag (true - do not compute orientation of features; false - compute orientation).");
@@ -253,7 +255,7 @@ class RTABMAP_EXP Parameters
RTABMAP_PARAM(SIFT, NFeatures, int, 0, "The number of best features to retain. The features are ranked by their scores (measured in SIFT algorithm as the local contrast)."); RTABMAP_PARAM(SIFT, NFeatures, int, 0, "The number of best features to retain. The features are ranked by their scores (measured in SIFT algorithm as the local contrast).");
RTABMAP_PARAM(SIFT, NOctaveLayers, int, 3, "The number of layers in each octave. 3 is the value used in D. Lowe paper. The number of octaves is computed automatically from the image resolution."); RTABMAP_PARAM(SIFT, NOctaveLayers, int, 3, "The number of layers in each octave. 3 is the value used in D. Lowe paper. The number of octaves is computed automatically from the image resolution.");
RTABMAP_PARAM(SIFT, ContrastThreshold, double, 0.04, "The contrast threshold used to filter out weak features in semi-uniform (low-contrast) regions. The larger the threshold, the less features are produced by the detector."); RTABMAP_PARAM(SIFT, ContrastThreshold, double, 0.04, "The contrast threshold used to filter out weak features in semi-uniform (low-contrast) regions. The larger the threshold, the less features are produced by the detector.");
RTABMAP_PARAM(SIFT, EdgeThreshold, double, 10.0, "The threshold used to filter out edge-like features. Note that the its meaning is different from the contrastThreshold, i.e. the larger the edgeThreshold, the less features are filtered out (more features are retained)."); RTABMAP_PARAM(SIFT, EdgeThreshold, double, 10, "The threshold used to filter out edge-like features. Note that the its meaning is different from the contrastThreshold, i.e. the larger the edgeThreshold, the less features are filtered out (more features are retained).");
RTABMAP_PARAM(SIFT, Sigma, double, 1.6, "The sigma of the Gaussian applied to the input image at the octave #0. If your image is captured with a weak camera with soft lenses, you might want to reduce the number."); RTABMAP_PARAM(SIFT, Sigma, double, 1.6, "The sigma of the Gaussian applied to the input image at the octave #0. If your image is captured with a weak camera with soft lenses, you might want to reduce the number.");
RTABMAP_PARAM(BRIEF, Bytes, int, 32, "Bytes is a length of descriptor in bytes. It can be equal 16, 32 or 64 bytes."); RTABMAP_PARAM(BRIEF, Bytes, int, 32, "Bytes is a length of descriptor in bytes. It can be equal 16, 32 or 64 bytes.");
@@ -267,7 +269,7 @@ class RTABMAP_EXP Parameters
RTABMAP_PARAM(FAST, GridRows, int, 4, "Grid rows (0 to disable). Adapts the detector to partition the source image into a grid and detect points in each cell."); RTABMAP_PARAM(FAST, GridRows, int, 4, "Grid rows (0 to disable). Adapts the detector to partition the source image into a grid and detect points in each cell.");
RTABMAP_PARAM(FAST, GridCols, int, 4, "Grid cols (0 to disable). Adapts the detector to partition the source image into a grid and detect points in each cell."); RTABMAP_PARAM(FAST, GridCols, int, 4, "Grid cols (0 to disable). Adapts the detector to partition the source image into a grid and detect points in each cell.");
RTABMAP_PARAM(GFTT, QualityLevel, double, 0.001, ""); RTABMAP_PARAM(GFTT, QualityLevel, double, 0.01, "");
RTABMAP_PARAM(GFTT, MinDistance, double, 5, ""); RTABMAP_PARAM(GFTT, MinDistance, double, 5, "");
RTABMAP_PARAM(GFTT, BlockSize, int, 3, ""); RTABMAP_PARAM(GFTT, BlockSize, int, 3, "");
RTABMAP_PARAM(GFTT, UseHarrisDetector, bool, false, ""); RTABMAP_PARAM(GFTT, UseHarrisDetector, bool, false, "");
@@ -284,12 +286,12 @@ class RTABMAP_EXP Parameters
RTABMAP_PARAM(FREAK, OrientationNormalized, bool, true, "Enable orientation normalization."); RTABMAP_PARAM(FREAK, OrientationNormalized, bool, true, "Enable orientation normalization.");
RTABMAP_PARAM(FREAK, ScaleNormalized, bool, true, "Enable scale normalization."); RTABMAP_PARAM(FREAK, ScaleNormalized, bool, true, "Enable scale normalization.");
RTABMAP_PARAM(FREAK, PatternScale, float, 22.0, "Scaling of the description pattern."); RTABMAP_PARAM(FREAK, PatternScale, float, 22, "Scaling of the description pattern.");
RTABMAP_PARAM(FREAK, NOctaves, int, 4, "Number of octaves covered by the detected keypoints."); RTABMAP_PARAM(FREAK, NOctaves, int, 4, "Number of octaves covered by the detected keypoints.");
RTABMAP_PARAM(BRISK, Thresh, int, 30, "FAST/AGAST detection threshold score."); RTABMAP_PARAM(BRISK, Thresh, int, 30, "FAST/AGAST detection threshold score.");
RTABMAP_PARAM(BRISK, Octaves, int, 3, "Detection octaves. Use 0 to do single scale."); RTABMAP_PARAM(BRISK, Octaves, int, 3, "Detection octaves. Use 0 to do single scale.");
RTABMAP_PARAM(BRISK, PatternScale, float, 1.0, "Apply this scale to the pattern used for sampling the neighbourhood of a keypoint."); RTABMAP_PARAM(BRISK, PatternScale, float, 1, "Apply this scale to the pattern used for sampling the neighbourhood of a keypoint.");
// BayesFilter // BayesFilter
RTABMAP_PARAM(Bayes, VirtualPlacePriorThr, float, 0.9, "Virtual place prior"); RTABMAP_PARAM(Bayes, VirtualPlacePriorThr, float, 0.9, "Virtual place prior");
@@ -298,7 +300,7 @@ class RTABMAP_EXP Parameters
// Verify hypotheses // Verify hypotheses
RTABMAP_PARAM(VhEp, MatchCountMin, int, 8, "Minimum of matching visual words pairs to accept the loop hypothesis."); RTABMAP_PARAM(VhEp, MatchCountMin, int, 8, "Minimum of matching visual words pairs to accept the loop hypothesis.");
RTABMAP_PARAM(VhEp, RansacParam1, float, 3.0, "Fundamental matrix (see cvFindFundamentalMat()): Max distance (in pixels) from the epipolar line for a point to be inlier."); RTABMAP_PARAM(VhEp, RansacParam1, float, 3, "Fundamental matrix (see cvFindFundamentalMat()): Max distance (in pixels) from the epipolar line for a point to be inlier.");
RTABMAP_PARAM(VhEp, RansacParam2, float, 0.99, "Fundamental matrix (see cvFindFundamentalMat()): Performance of the RANSAC."); RTABMAP_PARAM(VhEp, RansacParam2, float, 0.99, "Fundamental matrix (see cvFindFundamentalMat()): Performance of the RANSAC.");
// RGB-D SLAM // RGB-D SLAM
@@ -307,46 +309,54 @@ class RTABMAP_EXP Parameters
RTABMAP_PARAM(RGBD, AngularUpdate, float, 0.1, "Minimum angular displacement to update the map. Rehearsal is done prior to this, so weights are still updated."); RTABMAP_PARAM(RGBD, AngularUpdate, float, 0.1, "Minimum angular displacement to update the map. Rehearsal is done prior to this, so weights are still updated.");
RTABMAP_PARAM(RGBD, NewMapOdomChangeDistance, float, 0, "A new map is created if a change of odometry translation greater than X m is detected (0 m = disabled)."); RTABMAP_PARAM(RGBD, NewMapOdomChangeDistance, float, 0, "A new map is created if a change of odometry translation greater than X m is detected (0 m = disabled).");
RTABMAP_PARAM(RGBD, OptimizeFromGraphEnd, bool, false, "Optimize graph from the newest node. If false, the graph is optimized from the oldest node of the current graph (this adds an overhead computation to detect to oldest mode of the current graph, but it can be useful to preserve the map referential from the oldest node). Warning when set to false: when some nodes are transferred, the first referential of the local map may change, resulting in momentary changes in robot/map position (which are annoying in teleoperation)."); RTABMAP_PARAM(RGBD, OptimizeFromGraphEnd, bool, false, "Optimize graph from the newest node. If false, the graph is optimized from the oldest node of the current graph (this adds an overhead computation to detect to oldest mode of the current graph, but it can be useful to preserve the map referential from the oldest node). Warning when set to false: when some nodes are transferred, the first referential of the local map may change, resulting in momentary changes in robot/map position (which are annoying in teleoperation).");
RTABMAP_PARAM(RGBD, OptimizeMaxError, float, 1.0, "Reject loop closures if optimization error is greater than this value (0=disabled). This will help to detect when a wrong loop closure is added to the graph. Not compatible with \"Optimizer/Robust\" if enabled."); RTABMAP_PARAM(RGBD, OptimizeMaxError, float, 1, uFormat("Reject loop closures if optimization error is greater than this value (0=disabled). This will help to detect when a wrong loop closure is added to the graph. Not compatible with \"%s\" if enabled.", kOptimizerRobust().c_str()));
RTABMAP_PARAM(RGBD, GoalReachedRadius, float, 0.5, "Goal reached radius (m)."); RTABMAP_PARAM(RGBD, GoalReachedRadius, float, 0.5, "Goal reached radius (m).");
RTABMAP_PARAM(RGBD, PlanStuckIterations, int, 0, "Mark the current goal node on the path as unreachable if it is not updated after X iterations (0=disabled). If all upcoming nodes on the path are unreachabled, the plan fails."); RTABMAP_PARAM(RGBD, PlanStuckIterations, int, 0, "Mark the current goal node on the path as unreachable if it is not updated after X iterations (0=disabled). If all upcoming nodes on the path are unreachabled, the plan fails.");
RTABMAP_PARAM(RGBD, PlanLinearVelocity, float, 0.0, "Linear velocity (m/sec) used to compute path weights."); RTABMAP_PARAM(RGBD, PlanLinearVelocity, float, 0, "Linear velocity (m/sec) used to compute path weights.");
RTABMAP_PARAM(RGBD, PlanAngularVelocity, float, 0.0, "Angular velocity (rad/sec) used to compute path weights."); RTABMAP_PARAM(RGBD, PlanAngularVelocity, float, 0, "Angular velocity (rad/sec) used to compute path weights.");
RTABMAP_PARAM(RGBD, GoalsSavedInUserData, bool, false, "When a goal is received and processed with success, it is saved in user data of the location with this format: \"GOAL:#\"."); RTABMAP_PARAM(RGBD, GoalsSavedInUserData, bool, false, "When a goal is received and processed with success, it is saved in user data of the location with this format: \"GOAL:#\".");
RTABMAP_PARAM(RGBD, MaxLocalRetrieved, unsigned int, 2, "Maximum local locations retrieved (0=disabled) near the current pose in the local map or on the current planned path (those on the planned path have priority)."); RTABMAP_PARAM(RGBD, MaxLocalRetrieved, unsigned int, 2, "Maximum local locations retrieved (0=disabled) near the current pose in the local map or on the current planned path (those on the planned path have priority).");
RTABMAP_PARAM(RGBD, LocalRadius, float, 10, "Local radius (m) for nodes selection in the local map. This parameter is used in some approaches about the local map management."); RTABMAP_PARAM(RGBD, LocalRadius, float, 10, "Local radius (m) for nodes selection in the local map. This parameter is used in some approaches about the local map management.");
RTABMAP_PARAM(RGBD, LocalImmunizationRatio, float, 0.25, "Ratio of working memory for which local nodes are immunized from transfer."); RTABMAP_PARAM(RGBD, LocalImmunizationRatio, float, 0.25, "Ratio of working memory for which local nodes are immunized from transfer.");
RTABMAP_PARAM(RGBD, ScanMatchingIdsSavedInLinks, bool, true, "Save scan matching IDs in link's user data."); RTABMAP_PARAM(RGBD, ScanMatchingIdsSavedInLinks, bool, true, "Save scan matching IDs in link's user data.");
RTABMAP_PARAM(RGBD, NeighborLinkRefining, bool, false, "When a new node is added to the graph, the transformation of its neighbor link to the previous node is refined using ICP (laser scans required!)."); 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, LoopClosureReextractFeatures, bool, false, "Extract features even if there are some already in the nodes."); RTABMAP_PARAM(RGBD, LoopClosureReextractFeatures, bool, false, "Extract features even if there are some already in the nodes.");
RTABMAP_PARAM(RGBD, CreateOccupancyGrid, bool, false, "Create local occupancy grid maps. See \"Grid\" group for parameters.");
// Local/Proximity loop closure detection // Local/Proximity loop closure detection
RTABMAP_PARAM(RGBD, ProximityByTime, bool, false, "Detection over all locations in STM."); RTABMAP_PARAM(RGBD, ProximityByTime, bool, false, "Detection over all locations in STM.");
RTABMAP_PARAM(RGBD, ProximityBySpace, bool, true, "Detection over locations (in Working Memory or STM) near in space."); RTABMAP_PARAM(RGBD, ProximityBySpace, bool, true, "Detection over locations (in Working Memory or STM) near in space.");
RTABMAP_PARAM(RGBD, ProximityMaxGraphDepth, int, 50, "Maximum depth from the current/last loop closure location and the local loop closure hypotheses. Set 0 to ignore."); RTABMAP_PARAM(RGBD, ProximityMaxGraphDepth, int, 50, "Maximum depth from the current/last loop closure location and the local loop closure hypotheses. Set 0 to ignore.");
RTABMAP_PARAM(RGBD, ProximityPathFilteringRadius, float, 0.5, "Path filtering radius."); RTABMAP_PARAM(RGBD, ProximityMaxPaths, int, 3, "Maximum paths compared (from the most recent) for proximity detection by space. 0 means no limit.");
RTABMAP_PARAM(RGBD, ProximityPathFilteringRadius, float, 0.5, "Path filtering radius to reduce the number of nodes to compare in a path. A path should also be inside that radius to be considered for proximity detection.");
RTABMAP_PARAM(RGBD, ProximityPathMaxNeighbors, int, 10, "Maximum neighbor nodes compared on each path.");
RTABMAP_PARAM(RGBD, ProximityPathRawPosesUsed, bool, true, "When comparing to a local path, merge the scan using the odometry poses (with neighbor link optimizations) instead of the ones in the optimized local graph."); RTABMAP_PARAM(RGBD, ProximityPathRawPosesUsed, bool, true, "When comparing to a local path, merge the scan using the odometry poses (with neighbor link optimizations) instead of the ones in the optimized local graph.");
RTABMAP_PARAM(RGBD, ProximityAngle, float, 45.0, "Maximum angle (degrees) for visual proximity detection."); RTABMAP_PARAM(RGBD, ProximityAngle, float, 45, "Maximum angle (degrees) for visual proximity detection.");
// Graph optimization // Graph optimization
#ifdef RTABMAP_GTSAM #ifdef RTABMAP_GTSAM
RTABMAP_PARAM(Optimizer, Strategy, int, 2, "Graph optimization strategy: 0=TORO, 1=g2o and 2=GTSAM."); RTABMAP_PARAM(Optimizer, Strategy, int, 2, "Graph optimization strategy: 0=TORO, 1=g2o and 2=GTSAM.");
RTABMAP_PARAM(Optimizer, Iterations, int, 20, "Optimization iterations.");
RTABMAP_PARAM(Optimizer, Epsilon, double, 0.00001, "Stop optimizing when the error improvement is less than this value.");
#else #else
#ifdef RTABMAP_G2O #ifdef RTABMAP_G2O
RTABMAP_PARAM(Optimizer, Strategy, int, 1, "Graph optimization strategy: 0=TORO, 1=g2o and 2=GTSAM."); RTABMAP_PARAM(Optimizer, Strategy, int, 1, "Graph optimization strategy: 0=TORO, 1=g2o and 2=GTSAM.");
RTABMAP_PARAM(Optimizer, Iterations, int, 20, "Optimization iterations.");
RTABMAP_PARAM(Optimizer, Epsilon, double, 0.0, "Stop optimizing when the error improvement is less than this value.");
#else #else
RTABMAP_PARAM(Optimizer, Strategy, int, 0, "Graph optimization strategy: 0=TORO, 1=g2o and 2=GTSAM."); RTABMAP_PARAM(Optimizer, Strategy, int, 0, "Graph optimization strategy: 0=TORO, 1=g2o and 2=GTSAM.");
#endif
#endif
RTABMAP_PARAM(Optimizer, Iterations, int, 100, "Optimization iterations."); RTABMAP_PARAM(Optimizer, Iterations, int, 100, "Optimization iterations.");
RTABMAP_PARAM(Optimizer, Slam2D, bool, false, "If optimization is done only on x,y and theta (3DoF). Otherwise, it is done on full 6DoF poses."); RTABMAP_PARAM(Optimizer, Epsilon, double, 0.00001, "Stop optimizing when the error improvement is less than this value.");
#endif
#endif
RTABMAP_PARAM(Optimizer, VarianceIgnored, bool, false, "Ignore constraints' variance. If checked, identity information matrix is used for each constraint. Otherwise, an information matrix is generated from the variance saved in the links."); RTABMAP_PARAM(Optimizer, VarianceIgnored, bool, false, "Ignore constraints' variance. If checked, identity information matrix is used for each constraint. Otherwise, an information matrix is generated from the variance saved in the links.");
RTABMAP_PARAM(Optimizer, Epsilon, double, 0.0001, "Stop optimizing when the error improvement is less than this value."); RTABMAP_PARAM(Optimizer, Robust, bool, false, uFormat("Robust graph optimization using Vertigo (only work for g2o and GTSAM optimization strategies). Not compatible with \"%s\" if enabled.", kRGBDOptimizeMaxError().c_str()));
RTABMAP_PARAM(Optimizer, Robust, bool, false, "Robust graph optimization using Vertigo (only work for g2o and GTSAM optimization strategies). Not compatible with \"RGBD/OptimizeMaxError\" if enabled.");
RTABMAP_PARAM(g2o, Solver, int, 0, "0=csparse 1=pcg 2=cholmod"); RTABMAP_PARAM(g2o, Solver, int, 0, "0=csparse 1=pcg 2=cholmod 3=Eigen");
RTABMAP_PARAM(g2o, Optimizer, int, 0, "0=Levenberg 1=GaussNewton"); RTABMAP_PARAM(g2o, Optimizer, int, 0, "0=Levenberg 1=GaussNewton");
RTABMAP_PARAM(g2o, PixelVariance, double, 1.0, "Pixel variance used for SBA."); RTABMAP_PARAM(g2o, PixelVariance, double, 1.0, "Pixel variance used for bundle adjustment.");
RTABMAP_PARAM(g2o, RobustKernelDelta, double, 8, "Robust kernel delta used for bundle adjustment (0 means don't use robust kernel). Observations with chi2 over this threshold will be ignored in the second optimization pass.");
RTABMAP_PARAM(g2o, Baseline, double, 0.075, "When doing bundle adjustment with RGB-D data, we can set a fake baseline (m) to do stereo bundle adjustment (if 0, mono bundle adjustment is done). For stereo data, the baseline in the calibration is used directly.");
// Odometry // Odometry
RTABMAP_PARAM(Odom, Strategy, int, 0, "0=Frame-to-Map (F2M) 1=Frame-to-Frame (F2F)"); RTABMAP_PARAM(Odom, Strategy, int, 0, "0=Frame-to-Map (F2M) 1=Frame-to-Frame (F2F)");
@@ -364,15 +374,18 @@ class RTABMAP_EXP Parameters
RTABMAP_PARAM(Odom, KalmanMeasurementNoise, float, 0.01, "Process measurement covariance value."); RTABMAP_PARAM(Odom, KalmanMeasurementNoise, float, 0.01, "Process measurement covariance value.");
RTABMAP_PARAM(Odom, GuessMotion, bool, false, "Guess next transformation from the last motion computed."); RTABMAP_PARAM(Odom, GuessMotion, bool, false, "Guess next transformation from the last motion computed.");
RTABMAP_PARAM(Odom, KeyFrameThr, float, 0.3, "[Visual] Create a new keyframe when the number of inliers drops under this ratio of features in last frame. Setting the value to 0 means that a keyframe is created for each processed frame."); RTABMAP_PARAM(Odom, KeyFrameThr, float, 0.3, "[Visual] Create a new keyframe when the number of inliers drops under this ratio of features in last frame. Setting the value to 0 means that a keyframe is created for each processed frame.");
RTABMAP_PARAM(Odom, VisKeyFrameThr, int, 100, "[Visual] Create a new keyframe when the number of inliers drops under this threshold. Setting the value to 0 means that a keyframe is created for each processed frame.");
RTABMAP_PARAM(Odom, ScanKeyFrameThr, float, 0.7, "[Geometry] Create a new keyframe when the number of ICP inliers drops under this ratio of points in last frame's scan. Setting the value to 0 means that a keyframe is created for each processed frame."); RTABMAP_PARAM(Odom, ScanKeyFrameThr, float, 0.7, "[Geometry] Create a new keyframe when the number of ICP inliers drops under this ratio of points in last frame's scan. Setting the value to 0 means that a keyframe is created for each processed frame.");
RTABMAP_PARAM(Odom, ImageDecimation, int, 1, "Decimation of the images before registration."); RTABMAP_PARAM(Odom, ImageDecimation, int, 1, "Decimation of the images before registration. Negative decimation is done from RGB size instead of depth size (if depth is smaller than RGB, it may be interpolated depending of the decimation value).");
RTABMAP_PARAM(Odom, AlignWithGround, bool, false, "Align odometry with the ground on initialization.");
// Odometry Bag-of-words // Odometry Bag-of-words
RTABMAP_PARAM(OdomF2M, MaxSize, int, 2000, "[Visual] Local map size: If > 0 (example 5000), the odometry will maintain a local map of X maximum words."); RTABMAP_PARAM(OdomF2M, MaxSize, int, 2000, "[Visual] Local map size: If > 0 (example 5000), the odometry will maintain a local map of X maximum words.");
RTABMAP_PARAM(OdomF2M, MaxNewFeatures, int, 0, "[Visual] Maximum features (sorted by keypoint response) added to local map from a new key-frame. 0 means no limit."); RTABMAP_PARAM(OdomF2M, MaxNewFeatures, int, 0, "[Visual] Maximum features (sorted by keypoint response) added to local map from a new key-frame. 0 means no limit.");
RTABMAP_PARAM(OdomF2M, ScanMaxSize, int, 2000, "[Geometry] Maximum local scan map size."); RTABMAP_PARAM(OdomF2M, ScanMaxSize, int, 2000, "[Geometry] Maximum local scan map size.");
RTABMAP_PARAM(OdomF2M, ScanSubstractRadius, float, 0.05, "[Geometry] Radius used to filter points of a new added scan to local map. This could match the voxel size of the scans."); RTABMAP_PARAM(OdomF2M, ScanSubtractRadius, float, 0.05, "[Geometry] Radius used to filter points of a new added scan to local map. This could match the voxel size of the scans.");
RTABMAP_PARAM_STR(OdomF2M, FixedMapPath, "", "Path to a fixed map (RTAB-Map's database) to be used for odometry. Odometry will be constraint to this map. RGB-only images can be used if odometry PnP estimation is used.") RTABMAP_PARAM(OdomF2M, BundleAdjustment, int, 0, "Local bundle adjustment: 0=disabled, 1=g2o, 2=cvsba.");
RTABMAP_PARAM(OdomF2M, BundleAdjustmentMaxFrames, int, 0, "Maximum frames used for bundle adjustment (0=inf or all current frames in the local map).");
// Odometry Mono // Odometry Mono
RTABMAP_PARAM(OdomMono, InitMinFlow, float, 100, "Minimum optical flow required for the initialization step."); RTABMAP_PARAM(OdomMono, InitMinFlow, float, 100, "Minimum optical flow required for the initialization step.");
@@ -388,12 +401,12 @@ class RTABMAP_EXP Parameters
// Visual registration parameters // Visual registration parameters
RTABMAP_PARAM(Vis, EstimationType, int, 0, "Motion estimation approach: 0:3D->3D, 1:3D->2D (PnP), 2:2D->2D (Epipolar Geometry)"); RTABMAP_PARAM(Vis, EstimationType, int, 0, "Motion estimation approach: 0:3D->3D, 1:3D->2D (PnP), 2:2D->2D (Epipolar Geometry)");
RTABMAP_PARAM(Vis, ForwardEstOnly, bool, true, "Forward estimation only (A->B). If false, a transformation is also computed in backward direction (B->A), then the two resulting transforms are merged (middle interpolation between the transforms)."); RTABMAP_PARAM(Vis, ForwardEstOnly, bool, true, "Forward estimation only (A->B). If false, a transformation is also computed in backward direction (B->A), then the two resulting transforms are merged (middle interpolation between the transforms).");
RTABMAP_PARAM(Vis, InlierDistance, float, 0.1, "[Vis/EstimationType = 0] Maximum distance for feature correspondences. Used by 3D->3D estimation approach."); RTABMAP_PARAM(Vis, InlierDistance, float, 0.1, uFormat("[%s = 0] Maximum distance for feature correspondences. Used by 3D->3D estimation approach.", kVisEstimationType().c_str()));
RTABMAP_PARAM(Vis, RefineIterations, int, 5, "[Vis/EstimationType = 0] Number of iterations used to refine the transformation found by RANSAC. 0 means that the transformation is not refined."); RTABMAP_PARAM(Vis, RefineIterations, int, 5, uFormat("[%s = 0] Number of iterations used to refine the transformation found by RANSAC. 0 means that the transformation is not refined.", kVisEstimationType().c_str()));
RTABMAP_PARAM(Vis, PnPReprojError, float, 2.0, "[Vis/EstimationType = 1] PnP reprojection error."); RTABMAP_PARAM(Vis, PnPReprojError, float, 2, uFormat("[%s = 1] PnP reprojection error.", kVisEstimationType().c_str()));
RTABMAP_PARAM(Vis, PnPFlags, int, 1, "[Vis/EstimationType = 1] PnP flags: 0=Iterative, 1=EPNP, 2=P3P"); RTABMAP_PARAM(Vis, PnPFlags, int, 0, uFormat("[%s = 1] PnP flags: 0=Iterative, 1=EPNP, 2=P3P", kVisEstimationType().c_str()));
RTABMAP_PARAM(Vis, PnPRefineIterations, int, 1, "[Vis/EstimationType = 1] Refine iterations."); RTABMAP_PARAM(Vis, PnPRefineIterations, int, 1, uFormat("[%s = 1] Refine iterations.", kVisEstimationType().c_str()));
RTABMAP_PARAM(Vis, EpipolarGeometryVar, float, 0.02, "[Vis/EstimationType = 2] Epipolar geometry maximum variance to accept the transformation."); RTABMAP_PARAM(Vis, EpipolarGeometryVar, float, 0.02, 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."); RTABMAP_PARAM(Vis, MinInliers, int, 20, "Minimum feature correspondences to compute/accept the transformation.");
RTABMAP_PARAM(Vis, Iterations, int, 100, "Maximum iterations to compute the transform."); RTABMAP_PARAM(Vis, Iterations, int, 100, "Maximum iterations to compute the transform.");
#ifndef RTABMAP_NONFREE #ifndef RTABMAP_NONFREE
@@ -408,29 +421,30 @@ class RTABMAP_EXP Parameters
#endif #endif
RTABMAP_PARAM(Vis, MaxFeatures, int, 1000, "0 no limits."); RTABMAP_PARAM(Vis, MaxFeatures, int, 1000, "0 no limits.");
RTABMAP_PARAM(Vis, MaxDepth, float, 0.0, "Max depth of the features (0 means no limit)."); RTABMAP_PARAM(Vis, MaxDepth, float, 0, "Max depth of the features (0 means no limit).");
RTABMAP_PARAM(Vis, MinDepth, float, 0.0, "Min depth of the features (0 means no limit)."); RTABMAP_PARAM(Vis, MinDepth, float, 0, "Min depth of the features (0 means no limit).");
RTABMAP_PARAM_STR(Vis, RoiRatios, "0.0 0.0 0.0 0.0", "Region of interest ratios [left, right, top, bottom]."); RTABMAP_PARAM_STR(Vis, RoiRatios, "0.0 0.0 0.0 0.0", "Region of interest ratios [left, right, top, bottom].");
RTABMAP_PARAM(Vis, SubPixWinSize, int, 3, "See cv::cornerSubPix()."); RTABMAP_PARAM(Vis, SubPixWinSize, int, 3, "See cv::cornerSubPix().");
RTABMAP_PARAM(Vis, SubPixIterations, int, 0, "See cv::cornerSubPix(). 0 disables sub pixel refining."); RTABMAP_PARAM(Vis, SubPixIterations, int, 0, "See cv::cornerSubPix(). 0 disables sub pixel refining.");
RTABMAP_PARAM(Vis, SubPixEps, float, 0.02, "See cv::cornerSubPix()."); RTABMAP_PARAM(Vis, SubPixEps, float, 0.02, "See cv::cornerSubPix().");
RTABMAP_PARAM(Vis, CorType, int, 0, "Correspondences computation approach: 0=Features Matching, 1=Optical Flow"); RTABMAP_PARAM(Vis, CorType, int, 0, "Correspondences computation approach: 0=Features Matching, 1=Optical Flow");
RTABMAP_PARAM(Vis, CorNNType, int, 1, "[Vis/CorrespondenceType=0] kNNFlannNaive=0, kNNFlannKdTree=1, kNNFlannLSH=2, kNNBruteForce=3, kNNBruteForceGPU=4. Used for features matching approach."); RTABMAP_PARAM(Vis, CorNNType, int, 1, uFormat("[%s=0] kNNFlannNaive=0, kNNFlannKdTree=1, kNNFlannLSH=2, kNNBruteForce=3, kNNBruteForceGPU=4. Used for features matching approach.", kVisCorType().c_str()));
RTABMAP_PARAM(Vis, CorNNDR, float, 0.8, "[Vis/CorrespondenceType=0] NNDR: nearest neighbor distance ratio. Used for features matching approach."); RTABMAP_PARAM(Vis, CorNNDR, float, 0.6, uFormat("[%s=0] NNDR: nearest neighbor distance ratio. Used for features matching approach.", kVisCorType().c_str()));
RTABMAP_PARAM(Vis, CorGuessWinSize, int, 50, "[Vis/CorrespondenceType=0] Matching window size (pixels) around projected points when a guess transform is provided to find correspondences. 0 means disabled."); RTABMAP_PARAM(Vis, CorGuessWinSize, int, 20, uFormat("[%s=0] Matching window size (pixels) around projected points when a guess transform is provided to find correspondences. 0 means disabled.", kVisCorType().c_str()));
RTABMAP_PARAM(Vis, CorFlowWinSize, int, 16, "[Vis/CorrespondenceType=1] See cv::calcOpticalFlowPyrLK(). Used for optical flow approach."); RTABMAP_PARAM(Vis, CorFlowWinSize, int, 16, uFormat("[%s=1] See cv::calcOpticalFlowPyrLK(). Used for optical flow approach.", kVisCorType().c_str()));
RTABMAP_PARAM(Vis, CorFlowIterations, int, 30, "[Vis/CorrespondenceType=1] See cv::calcOpticalFlowPyrLK(). Used for optical flow approach."); RTABMAP_PARAM(Vis, CorFlowIterations, int, 30, uFormat("[%s=1] See cv::calcOpticalFlowPyrLK(). Used for optical flow approach.", kVisCorType().c_str()));
RTABMAP_PARAM(Vis, CorFlowEps, float, 0.01, "[Vis/CorrespondenceType=1] See cv::calcOpticalFlowPyrLK(). Used for optical flow approach."); RTABMAP_PARAM(Vis, CorFlowEps, float, 0.01, uFormat("[%s=1] See cv::calcOpticalFlowPyrLK(). Used for optical flow approach.", kVisCorType().c_str()));
RTABMAP_PARAM(Vis, CorFlowMaxLevel, int, 3, "[Vis/CorrespondenceType=1] See cv::calcOpticalFlowPyrLK(). Used for optical flow approach."); RTABMAP_PARAM(Vis, CorFlowMaxLevel, int, 3, uFormat("[%s=1] See cv::calcOpticalFlowPyrLK(). Used for optical flow approach.", kVisCorType().c_str()));
RTABMAP_PARAM(Vis, BundleAdjustment, int, 0, "Optimization with bundle adjustment: 0=disabled, 1=g2o, 2=cvsba.");
// ICP registration parameters // ICP registration parameters
RTABMAP_PARAM(Icp, MaxTranslation, float, 0.2, "Maximum ICP translation correction accepted (m)."); RTABMAP_PARAM(Icp, MaxTranslation, float, 0.2, "Maximum ICP translation correction accepted (m).");
RTABMAP_PARAM(Icp, MaxRotation, float, 0.78, "Maximum ICP rotation correction accepted (rad)."); RTABMAP_PARAM(Icp, MaxRotation, float, 0.78, "Maximum ICP rotation correction accepted (rad).");
RTABMAP_PARAM(Icp, VoxelSize, float, 0.025, "Uniform sampling voxel size (0=disabled)."); RTABMAP_PARAM(Icp, VoxelSize, float, 0.0, "Uniform sampling voxel size (0=disabled).");
RTABMAP_PARAM(Icp, DownsamplingStep, int, 1, "Downsampling step size (1=no sampling). This is done before uniform sampling."); RTABMAP_PARAM(Icp, DownsamplingStep, int, 1, "Downsampling step size (1=no sampling). This is done before uniform sampling.");
RTABMAP_PARAM(Icp, MaxCorrespondenceDistance, float, 0.05, "Max distance for point correspondences."); RTABMAP_PARAM(Icp, MaxCorrespondenceDistance, float, 0.05, "Max distance for point correspondences.");
RTABMAP_PARAM(Icp, Iterations, int, 30, "Max iterations."); RTABMAP_PARAM(Icp, Iterations, int, 30, "Max iterations.");
RTABMAP_PARAM(Icp, Epsilon, float, 0.0, "Set the transformation epsilon (maximum allowable difference between two consecutive transformations) in order for an optimization to be considered as having converged to the final solution."); RTABMAP_PARAM(Icp, Epsilon, float, 0, "Set the transformation epsilon (maximum allowable difference between two consecutive transformations) in order for an optimization to be considered as having converged to the final solution.");
RTABMAP_PARAM(Icp, CorrespondenceRatio, float, 0.2, "Ratio of matching correspondences to accept the transform."); RTABMAP_PARAM(Icp, CorrespondenceRatio, float, 0.2, "Ratio of matching correspondences to accept the transform.");
RTABMAP_PARAM(Icp, PointToPlane, bool, false, "Use point to plane ICP."); RTABMAP_PARAM(Icp, PointToPlane, bool, false, "Use point to plane ICP.");
RTABMAP_PARAM(Icp, PointToPlaneNormalNeighbors, int, 20, "Number of neighbors to compute normals for point to plane."); RTABMAP_PARAM(Icp, PointToPlaneNormalNeighbors, int, 20, "Number of neighbors to compute normals for point to plane.");
@@ -441,14 +455,14 @@ class RTABMAP_EXP Parameters
RTABMAP_PARAM(Stereo, Iterations, int, 30, "Maximum iterations."); RTABMAP_PARAM(Stereo, Iterations, int, 30, "Maximum iterations.");
RTABMAP_PARAM(Stereo, MaxLevel, int, 3, "Maximum pyramid level."); RTABMAP_PARAM(Stereo, MaxLevel, int, 3, "Maximum pyramid level.");
RTABMAP_PARAM(Stereo, MinDisparity, int, 1, "Minimum disparity."); RTABMAP_PARAM(Stereo, MinDisparity, int, 1, "Minimum disparity.");
RTABMAP_PARAM(Stereo, MaxDisparity, int, 64, "Maximum disparity."); RTABMAP_PARAM(Stereo, MaxDisparity, int, 128, "Maximum disparity.");
RTABMAP_PARAM(Stereo, OpticalFlow, bool, true, "Use optical flow to find stereo correspondences, otherwise a simple block matching approach is used."); RTABMAP_PARAM(Stereo, OpticalFlow, bool, true, "Use optical flow to find stereo correspondences, otherwise a simple block matching approach is used.");
RTABMAP_PARAM(Stereo, SSD, bool, true, "[Stereo/OpticalFlow = false] Use Sum of Squared Differences (SSD) window, otherwise Sum of Absolute Differences (SAD) window is used."); RTABMAP_PARAM(Stereo, SSD, bool, true, uFormat("[%s=false] Use Sum of Squared Differences (SSD) window, otherwise Sum of Absolute Differences (SAD) window is used.", kStereoOpticalFlow().c_str()));
RTABMAP_PARAM(Stereo, Eps, double, 0.01, "[Stereo/OpticalFlow = true] Epsilon stop criterion."); RTABMAP_PARAM(Stereo, Eps, double, 0.01, uFormat("[%s=true] Epsilon stop criterion.", kStereoOpticalFlow().c_str()));
RTABMAP_PARAM(StereoBM, BlockSize, int, 15, "See cv::StereoBM"); RTABMAP_PARAM(StereoBM, BlockSize, int, 15, "See cv::StereoBM");
RTABMAP_PARAM(StereoBM, MinDisparity, int, 0, "See cv::StereoBM"); RTABMAP_PARAM(StereoBM, MinDisparity, int, 0, "See cv::StereoBM");
RTABMAP_PARAM(StereoBM, NumDisparities, int, 64, "See cv::StereoBM"); RTABMAP_PARAM(StereoBM, NumDisparities, int, 128, "See cv::StereoBM");
RTABMAP_PARAM(StereoBM, PreFilterSize, int, 9, "See cv::StereoBM"); RTABMAP_PARAM(StereoBM, PreFilterSize, int, 9, "See cv::StereoBM");
RTABMAP_PARAM(StereoBM, PreFilterCap, int, 31, "See cv::StereoBM"); RTABMAP_PARAM(StereoBM, PreFilterCap, int, 31, "See cv::StereoBM");
RTABMAP_PARAM(StereoBM, UniquenessRatio, int, 15, "See cv::StereoBM"); RTABMAP_PARAM(StereoBM, UniquenessRatio, int, 15, "See cv::StereoBM");
@@ -456,6 +470,38 @@ class RTABMAP_EXP Parameters
RTABMAP_PARAM(StereoBM, SpeckleWindowSize, int, 100, "See cv::StereoBM"); RTABMAP_PARAM(StereoBM, SpeckleWindowSize, int, 100, "See cv::StereoBM");
RTABMAP_PARAM(StereoBM, SpeckleRange, int, 4, "See cv::StereoBM"); RTABMAP_PARAM(StereoBM, SpeckleRange, int, 4, "See cv::StereoBM");
// 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, DepthDecimation, int, 4, uFormat("[%s=true] Decimation of the depth image before creating cloud. Negative decimation is done from RGB size instead of depth size (if depth is smaller than RGB, it may be interpolated depending of the decimation value).", kGridDepthDecimation().c_str()));
RTABMAP_PARAM(Grid, DepthMin, float, 0.0, uFormat("[%s=true] Minimum cloud's depth from sensor.", kGridFromDepth().c_str()));
RTABMAP_PARAM(Grid, DepthMax, float, 4.0, uFormat("[%s=true] Maximum cloud's depth from sensor. 0=inf.", kGridFromDepth().c_str()));
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(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, CellSize, float, 0.05, "Resolution of the occupancy grid.");
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.");
RTABMAP_PARAM(Grid, NormalsSegmentation, bool, true, "Segment ground from obstacles using point normals, otherwise a fast passthrough is used.");
RTABMAP_PARAM(Grid, MaxObstacleHeight, float, 0.0, "Maximum obstacles height (0=disabled).");
RTABMAP_PARAM(Grid, MinGroundHeight, float, 0.0, "Minimum ground height (0=disabled).");
RTABMAP_PARAM(Grid, MaxGroundHeight, float, 0.0, uFormat("Maximum ground height (0=disabled). Should be set if \"%s\" is true.", kGridNormalsSegmentation().c_str()));
RTABMAP_PARAM(Grid, MaxGroundAngle, float, 45, uFormat("[%s=true] Maximum angle (degrees) between point's normal to ground's normal to label it as ground. Points with higher angle difference are considered as obstacles.", kGridNormalsSegmentation().c_str()));
RTABMAP_PARAM(Grid, NormalK, int, 10, uFormat("[%s=true] K neighbors to compute normals.", kGridNormalsSegmentation().c_str()));
RTABMAP_PARAM(Grid, ClusterRadius, float, 0.1, uFormat("[%s=true] Cluster maximum radius.", kGridNormalsSegmentation().c_str()));
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. 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()));
#else
RTABMAP_PARAM(Grid, 3D, bool, false, uFormat("A 3D occupancy grid is required if you want an Octomap. 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()));
#endif
RTABMAP_PARAM(Grid, 3DGroundIsObstacle, bool, false, uFormat("[%s=true] Ground is an obstacle. Use this only if you want an Octomap with ground identified as an obstacle (e.g., with an UAV).", kGrid3D().c_str()));
RTABMAP_PARAM(Grid, NoiseFilteringRadius, float, 0.0, "Noise filtering radius (0=disabled). Done after segmentation.");
RTABMAP_PARAM(Grid, NoiseFilteringMinNeighbors, int, 5, "Noise filtering minimum neighbors.");
RTABMAP_PARAM(Grid, Scan2dUnknownSpaceFilled, bool, false, "Unknown space filled. Only used with 2D laser scans.");
RTABMAP_PARAM(Grid, Scan2dMaxFilledRange, float, 4.0, "Unknown space filled maximum range. If 0, the laser scan maximum range is used.");
public: public:
virtual ~Parameters(); virtual ~Parameters();
@@ -480,22 +526,25 @@ public:
*/ */
static std::string getDescription(const std::string & paramKey); static std::string getDescription(const std::string & paramKey);
static void parse(const ParametersMap & parameters, const std::string & key, bool & value); static bool parse(const ParametersMap & parameters, const std::string & key, bool & value);
static void parse(const ParametersMap & parameters, const std::string & key, int & value); static bool parse(const ParametersMap & parameters, const std::string & key, int & value);
static void parse(const ParametersMap & parameters, const std::string & key, unsigned int & value); static bool parse(const ParametersMap & parameters, const std::string & key, unsigned int & value);
static void parse(const ParametersMap & parameters, const std::string & key, float & value); static bool parse(const ParametersMap & parameters, const std::string & key, float & value);
static void parse(const ParametersMap & parameters, const std::string & key, double & value); static bool parse(const ParametersMap & parameters, const std::string & key, double & value);
static void parse(const ParametersMap & parameters, const std::string & key, std::string & value); static bool parse(const ParametersMap & parameters, const std::string & key, std::string & value);
static void parse(const ParametersMap & parameters, ParametersMap & parametersOut); static void parse(const ParametersMap & parameters, ParametersMap & parametersOut);
static const char * showUsage(); static const char * showUsage();
static ParametersMap parseArguments(int argc, char * argv[]); static ParametersMap parseArguments(int argc, char * argv[], bool onlyParameters = false);
static std::string getVersion(); static std::string getVersion();
static std::string getDefaultDatabaseName(); static std::string getDefaultDatabaseName();
static std::string serialize(const ParametersMap & parameters);
static ParametersMap deserialize(const std::string & parameters);
static bool isFeatureParameter(const std::string & param); static bool isFeatureParameter(const std::string & param);
static ParametersMap getDefaultOdometryParameters(bool stereo = false); static ParametersMap getDefaultOdometryParameters(bool stereo = false, bool vis = true, bool icp = false);
static ParametersMap getDefaultParameters(const std::string & group); static ParametersMap getDefaultParameters(const std::string & group);
static ParametersMap filterParameters(const ParametersMap & parameters, const std::string & group); static ParametersMap filterParameters(const ParametersMap & parameters, const std::string & group);

View File

@@ -1,5 +1,5 @@
/* /*
Copyright (c) 2010-2015, Mathieu Labbe - IntRoLab - Universite de Sherbrooke Copyright (c) 2010-2016, Mathieu Labbe - IntRoLab - Universite de Sherbrooke
All rights reserved. All rights reserved.
Redistribution and use in source and binary forms, with or without Redistribution and use in source and binary forms, with or without

View File

@@ -1,5 +1,5 @@
/* /*
Copyright (c) 2010-2014, Mathieu Labbe - IntRoLab - Universite de Sherbrooke Copyright (c) 2010-2016, Mathieu Labbe - IntRoLab - Universite de Sherbrooke
All rights reserved. All rights reserved.
Redistribution and use in source and binary forms, with or without Redistribution and use in source and binary forms, with or without

View File

@@ -1,5 +1,5 @@
/* /*
Copyright (c) 2010-2014, Mathieu Labbe - IntRoLab - Universite de Sherbrooke Copyright (c) 2010-2016, Mathieu Labbe - IntRoLab - Universite de Sherbrooke
All rights reserved. All rights reserved.
Redistribution and use in source and binary forms, with or without Redistribution and use in source and binary forms, with or without

View File

@@ -1,9 +1,29 @@
/* /*
* RegistrationInfo.h Copyright (c) 2010-2016, Mathieu Labbe - IntRoLab - Universite de Sherbrooke
* All rights reserved.
* Created on: Jan 5, 2016
* Author: mathieu Redistribution and use in source and binary forms, with or without
*/ modification, are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
* Neither the name of the Universite de Sherbrooke nor the
names of its contributors may be used to endorse or promote products
derived from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef REGISTRATIONINFO_H_ #ifndef REGISTRATIONINFO_H_
#define REGISTRATIONINFO_H_ #define REGISTRATIONINFO_H_
@@ -15,14 +35,18 @@ class RegistrationInfo
{ {
public: public:
RegistrationInfo() : RegistrationInfo() :
variance(0), varianceLin(0),
varianceAng(0),
inliers(0), inliers(0),
matches(0), matches(0),
icpInliersRatio(0) icpInliersRatio(0),
icpTranslation(0.0f),
icpRotation(0.0f)
{ {
} }
float variance; float varianceLin;
float varianceAng;
std::string rejectedMsg; std::string rejectedMsg;
// RegistrationVis // RegistrationVis
@@ -33,6 +57,8 @@ public:
// RegistrationIcp // RegistrationIcp
float icpInliersRatio; float icpInliersRatio;
float icpTranslation;
float icpRotation;
}; };
} }

View File

@@ -1,5 +1,5 @@
/* /*
Copyright (c) 2010-2014, Mathieu Labbe - IntRoLab - Universite de Sherbrooke Copyright (c) 2010-2016, Mathieu Labbe - IntRoLab - Universite de Sherbrooke
All rights reserved. All rights reserved.
Redistribution and use in source and binary forms, with or without Redistribution and use in source and binary forms, with or without
@@ -81,8 +81,10 @@ private:
int _flowMaxLevel; int _flowMaxLevel;
float _nndr; float _nndr;
int _guessWinSize; int _guessWinSize;
int _bundleAdjustment;
ParametersMap _featureParameters; ParametersMap _featureParameters;
ParametersMap _bundleParameters;
}; };
} }

View File

@@ -1,5 +1,5 @@
/* /*
Copyright (c) 2010-2014, Mathieu Labbe - IntRoLab - Universite de Sherbrooke Copyright (c) 2010-2016, Mathieu Labbe - IntRoLab - Universite de Sherbrooke
All rights reserved. All rights reserved.
Redistribution and use in source and binary forms, with or without Redistribution and use in source and binary forms, with or without
@@ -61,15 +61,23 @@ public:
bool process(const cv::Mat & image, int id=0); // for convenience, an id is automatically generated if id=0 bool process(const cv::Mat & image, int id=0); // for convenience, an id is automatically generated if id=0
bool process( bool process(
const SensorData & data, const SensorData & data,
const Transform & odomPose, Transform odomPose,
const cv::Mat & covariance = cv::Mat::eye(6,6,CV_64FC1)); // for convenience const cv::Mat & covariance = cv::Mat::eye(6,6,CV_64FC1)); // for convenience
void init(const ParametersMap & parameters, const std::string & databasePath = ""); void init(const ParametersMap & parameters, const std::string & databasePath = "");
void init(const std::string & configFile = "", const std::string & databasePath = ""); void init(const std::string & configFile = "", const std::string & databasePath = "");
void close(bool databaseSaved = true); /**
* Close rtabmap. This will delete rtabmap object if set.
* @param databaseSaved true=database saved, false=database discarded.
* @param databasePath output database file name, ignored if
* Db/Sqlite3InMemory=false (opened database is
* then overwritten).
*/
void close(bool databaseSaved = true, const std::string & ouputDatabasePath = "");
const std::string & getWorkingDir() const {return _wDir;} const std::string & getWorkingDir() const {return _wDir;}
bool isRGBDMode() const { return _rgbdSlamMode; }
int getLoopClosureId() const {return _loopClosureHypothesis.first;} int getLoopClosureId() const {return _loopClosureHypothesis.first;}
float getLoopClosureValue() const {return _loopClosureHypothesis.second;} float getLoopClosureValue() const {return _loopClosureHypothesis.second;}
int getHighestHypothesisId() const {return _highestHypothesis.first;} int getHighestHypothesisId() const {return _highestHypothesis.first;}
@@ -100,6 +108,13 @@ public:
int triggerNewMap(); int triggerNewMap();
bool labelLocation(int id, const std::string & label); bool labelLocation(int id, const std::string & label);
/**
* Set user data. Detect automatically if raw or compressed. If raw, the data is
* compressed too. A matrix of type CV_8UC1 with 1 row is considered as compressed.
* If you have one dimension unsigned 8 bits raw data, make sure to transpose it
* (to have multiple rows instead of multiple columns) in order to be detected as
* not compressed.
*/
bool setUserData(int id, const cv::Mat & data); bool setUserData(int id, const cv::Mat & data);
void generateDOTGraph(const std::string & path, int id=0, int margin=5); void generateDOTGraph(const std::string & path, int id=0, int margin=5);
void exportPoses( void exportPoses(
@@ -127,6 +142,7 @@ public:
bool global, bool global,
std::map<int, Signature> * signatures = 0); std::map<int, Signature> * signatures = 0);
int detectMoreLoopClosures(float clusterRadius = 0.5f, float clusterAngle = M_PI/6.0f, int iterations = 1); int detectMoreLoopClosures(float clusterRadius = 0.5f, float clusterAngle = M_PI/6.0f, int iterations = 1);
int refineLinks();
int getPathStatus() const {return _pathStatus;} // -1=failed 0=idle/executing 1=success int getPathStatus() const {return _pathStatus;} // -1=failed 0=idle/executing 1=success
void clearPath(int status); // -1=failed 0=idle/executing 1=success void clearPath(int status); // -1=failed 0=idle/executing 1=success
@@ -141,7 +157,7 @@ public:
const Transform & getPathTransformToGoal() const {return _pathTransformToGoal;} const Transform & getPathTransformToGoal() const {return _pathTransformToGoal;}
std::map<int, Transform> getForwardWMPoses(int fromId, int maxNearestNeighbors, float radius, int maxDiffID) const; std::map<int, Transform> getForwardWMPoses(int fromId, int maxNearestNeighbors, float radius, int maxDiffID) const;
std::list<std::map<int, Transform> > getPaths(std::map<int, Transform> poses) const; std::map<int, std::map<int, Transform> > getPaths(std::map<int, Transform> poses, const Transform & target, int maxGraphDepth = 0) const;
void adjustLikelihood(std::map<int, float> & likelihood) const; void adjustLikelihood(std::map<int, float> & likelihood) const;
std::pair<int, float> selectHypothesis(const std::map<int, float> & posterior, std::pair<int, float> selectHypothesis(const std::map<int, float> & posterior,
const std::map<int, float> & likelihood) const; const std::map<int, float> & likelihood) const;
@@ -194,6 +210,8 @@ private:
float _localRadius; float _localRadius;
float _localImmunizationRatio; float _localImmunizationRatio;
int _proximityMaxGraphDepth; int _proximityMaxGraphDepth;
int _proximityMaxPaths;
int _proximityMaxNeighbors;
float _proximityFilteringRadius; float _proximityFilteringRadius;
bool _proximityRawPosesUsed; bool _proximityRawPosesUsed;
float _proximityAngle; float _proximityAngle;
@@ -234,6 +252,7 @@ private:
std::map<int, Transform> _optimizedPoses; std::map<int, Transform> _optimizedPoses;
std::multimap<int, Link> _constraints; std::multimap<int, Link> _constraints;
Transform _mapCorrection; Transform _mapCorrection;
Transform _mapCorrectionBackup; // used in localization mode when odom is lost
Transform _lastLocalizationPose; // Corrected odometry pose. In mapping mode, this corresponds to last pose return by getLocalOptimizedPoses(). Transform _lastLocalizationPose; // Corrected odometry pose. In mapping mode, this corresponds to last pose return by getLocalOptimizedPoses().
int _lastLocalizationNodeId; // for localization mode int _lastLocalizationNodeId; // for localization mode
@@ -245,6 +264,7 @@ private:
unsigned int _pathGoalIndex; unsigned int _pathGoalIndex;
Transform _pathTransformToGoal; Transform _pathTransformToGoal;
int _pathStuckCount; int _pathStuckCount;
float _pathStuckDistance;
}; };

View File

@@ -1,5 +1,5 @@
/* /*
Copyright (c) 2010-2014, Mathieu Labbe - IntRoLab - Universite de Sherbrooke Copyright (c) 2010-2016, Mathieu Labbe - IntRoLab - Universite de Sherbrooke
All rights reserved. All rights reserved.
Redistribution and use in source and binary forms, with or without Redistribution and use in source and binary forms, with or without
@@ -61,7 +61,7 @@ public:
enum Cmd { enum Cmd {
kCmdInit, // params: [string] database path + ParametersMap kCmdInit, // params: [string] database path + ParametersMap
kCmdResetMemory, kCmdResetMemory,
kCmdClose, // params: [bool] database saved (default true) kCmdClose, // params: [bool] database saved (default true), [string] output database path (empty=use same database to save, only work when Db/Sqlite3InMemory=true)
kCmdDumpMemory, kCmdDumpMemory,
kCmdDumpPrediction, kCmdDumpPrediction,
kCmdGenerateDOTGraph, // params: [bool] global, [string] path, if global=false: [int] id, [int] margin kCmdGenerateDOTGraph, // params: [bool] global, [string] path, if global=false: [int] id, [int] margin

View File

@@ -1,5 +1,5 @@
/* /*
Copyright (c) 2010-2014, Mathieu Labbe - IntRoLab - Universite de Sherbrooke Copyright (c) 2010-2016, Mathieu Labbe - IntRoLab - Universite de Sherbrooke
All rights reserved. All rights reserved.
Redistribution and use in source and binary forms, with or without Redistribution and use in source and binary forms, with or without

View File

@@ -1,5 +1,5 @@
/* /*
Copyright (c) 2010-2014, Mathieu Labbe - IntRoLab - Universite de Sherbrooke Copyright (c) 2010-2016, Mathieu Labbe - IntRoLab - Universite de Sherbrooke
All rights reserved. All rights reserved.
Redistribution and use in source and binary forms, with or without Redistribution and use in source and binary forms, with or without
@@ -82,8 +82,14 @@ public:
void setDataBufferSize(unsigned int bufferSize); void setDataBufferSize(unsigned int bufferSize);
void createIntermediateNodes(bool enabled); void createIntermediateNodes(bool enabled);
// this will delete rtabmap object if set /**
void close(bool databaseSaved); * Close rtabmap. This will delete rtabmap object if set.
* @param databaseSaved true=database saved, false=database discarded.
* @param databasePath output database file name, ignored if
* Db/Sqlite3InMemory=false (opened database is
* then overwritten).
*/
void close(bool databaseSaved, const std::string & databasePath = "");
protected: protected:
virtual void handleEvent(UEvent * anEvent); virtual void handleEvent(UEvent * anEvent);

View File

@@ -1,5 +1,5 @@
/* /*
Copyright (c) 2010-2014, Mathieu Labbe - IntRoLab - Universite de Sherbrooke Copyright (c) 2010-2016, Mathieu Labbe - IntRoLab - Universite de Sherbrooke
All rights reserved. All rights reserved.
Redistribution and use in source and binary forms, with or without Redistribution and use in source and binary forms, with or without
@@ -33,6 +33,7 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include <rtabmap/core/CameraModel.h> #include <rtabmap/core/CameraModel.h>
#include <rtabmap/core/StereoCameraModel.h> #include <rtabmap/core/StereoCameraModel.h>
#include <rtabmap/core/Transform.h> #include <rtabmap/core/Transform.h>
#include <rtabmap/core/LaserScanInfo.h>
#include <opencv2/core/core.hpp> #include <opencv2/core/core.hpp>
#include <opencv2/features2d/features2d.hpp> #include <opencv2/features2d/features2d.hpp>
@@ -75,8 +76,7 @@ public:
// RGB-D constructor + laser scan // RGB-D constructor + laser scan
SensorData( SensorData(
const cv::Mat & laserScan, const cv::Mat & laserScan,
int laserScanMaxPts, const LaserScanInfo & laserScanInfo,
float laserScanMaxRange,
const cv::Mat & rgb, const cv::Mat & rgb,
const cv::Mat & depth, const cv::Mat & depth,
const CameraModel & cameraModel, const CameraModel & cameraModel,
@@ -96,8 +96,7 @@ public:
// Multi-cameras RGB-D constructor + laser scan // Multi-cameras RGB-D constructor + laser scan
SensorData( SensorData(
const cv::Mat & laserScan, const cv::Mat & laserScan,
int laserScanMaxPts, const LaserScanInfo & laserScanInfo,
float laserScanMaxRange,
const cv::Mat & rgb, const cv::Mat & rgb,
const cv::Mat & depth, const cv::Mat & depth,
const std::vector<CameraModel> & cameraModels, const std::vector<CameraModel> & cameraModels,
@@ -117,8 +116,7 @@ public:
// Stereo constructor + laser scan // Stereo constructor + laser scan
SensorData( SensorData(
const cv::Mat & laserScan, const cv::Mat & laserScan,
int laserScanMaxPts, const LaserScanInfo & laserScanInfo,
float laserScanMaxRange,
const cv::Mat & left, const cv::Mat & left,
const cv::Mat & right, const cv::Mat & right,
const StereoCameraModel & cameraModel, const StereoCameraModel & cameraModel,
@@ -131,7 +129,6 @@ public:
bool isValid() const { bool isValid() const {
return !(_id == 0 && return !(_id == 0 &&
_stamp == 0.0 && _stamp == 0.0 &&
_laserScanMaxPts == 0 &&
_imageRaw.empty() && _imageRaw.empty() &&
_imageCompressed.empty() && _imageCompressed.empty() &&
_depthOrRightRaw.empty() && _depthOrRightRaw.empty() &&
@@ -150,8 +147,7 @@ public:
void setId(int id) {_id = id;} void setId(int id) {_id = id;}
double stamp() const {return _stamp;} double stamp() const {return _stamp;}
void setStamp(double stamp) {_stamp = stamp;} void setStamp(double stamp) {_stamp = stamp;}
int laserScanMaxPts() const {return _laserScanMaxPts;} const LaserScanInfo & laserScanInfo() const {return _laserScanInfo;}
float laserScanMaxRange() const {return _laserScanMaxRange;}
const cv::Mat & imageCompressed() const {return _imageCompressed;} const cv::Mat & imageCompressed() const {return _imageCompressed;}
const cv::Mat & depthOrRightCompressed() const {return _depthOrRightCompressed;} const cv::Mat & depthOrRightCompressed() const {return _depthOrRightCompressed;}
@@ -162,7 +158,7 @@ public:
const cv::Mat & laserScanRaw() const {return _laserScanRaw;} const cv::Mat & laserScanRaw() const {return _laserScanRaw;}
void setImageRaw(const cv::Mat & imageRaw) {_imageRaw = imageRaw;} void setImageRaw(const cv::Mat & imageRaw) {_imageRaw = imageRaw;}
void setDepthOrRightRaw(const cv::Mat & depthOrImageRaw) {_depthOrRightRaw =depthOrImageRaw;} void setDepthOrRightRaw(const cv::Mat & depthOrImageRaw) {_depthOrRightRaw =depthOrImageRaw;}
void setLaserScanRaw(const cv::Mat & laserScanRaw, int maxPts, float maxRange) {_laserScanRaw =laserScanRaw;_laserScanMaxPts = maxPts;_laserScanMaxRange=maxRange;} void setLaserScanRaw(const cv::Mat & laserScanRaw, const LaserScanInfo & info) {_laserScanRaw =laserScanRaw;_laserScanInfo = info;}
void setCameraModel(const CameraModel & model) {_cameraModels.clear(); _cameraModels.push_back(model);} void setCameraModel(const CameraModel & model) {_cameraModels.clear(); _cameraModels.push_back(model);}
void setCameraModels(const std::vector<CameraModel> & models) {_cameraModels = models;} void setCameraModels(const std::vector<CameraModel> & models) {_cameraModels = models;}
void setStereoCameraModel(const StereoCameraModel & stereoCameraModel) {_stereoCameraModel = stereoCameraModel;} void setStereoCameraModel(const StereoCameraModel & stereoCameraModel) {_stereoCameraModel = stereoCameraModel;}
@@ -172,33 +168,64 @@ public:
cv::Mat rightRaw() const {return _depthOrRightRaw.type()==CV_8UC1?_depthOrRightRaw:cv::Mat();} cv::Mat rightRaw() const {return _depthOrRightRaw.type()==CV_8UC1?_depthOrRightRaw:cv::Mat();}
void uncompressData(); void uncompressData();
void uncompressData(cv::Mat * imageRaw, cv::Mat * depthOrRightRaw, cv::Mat * laserScanRaw = 0, cv::Mat * userDataRaw = 0); void uncompressData(
void uncompressDataConst(cv::Mat * imageRaw, cv::Mat * depthOrRightRaw, cv::Mat * laserScanRaw = 0, cv::Mat * userDataRaw = 0) const; cv::Mat * imageRaw,
cv::Mat * depthOrRightRaw,
cv::Mat * laserScanRaw = 0,
cv::Mat * userDataRaw = 0,
cv::Mat * groundCellsRaw = 0,
cv::Mat * obstacleCellsRaw = 0);
void uncompressDataConst(
cv::Mat * imageRaw,
cv::Mat * depthOrRightRaw,
cv::Mat * laserScanRaw = 0,
cv::Mat * userDataRaw = 0,
cv::Mat * groundCellsRaw = 0,
cv::Mat * obstacleCellsRaw = 0) const;
const std::vector<CameraModel> & cameraModels() const {return _cameraModels;} const std::vector<CameraModel> & cameraModels() const {return _cameraModels;}
const StereoCameraModel & stereoCameraModel() const {return _stereoCameraModel;} const StereoCameraModel & stereoCameraModel() const {return _stereoCameraModel;}
void setUserDataRaw(const cv::Mat & userDataRaw); // only set raw void setUserDataRaw(const cv::Mat & userDataRaw); // only set raw
void setUserData(const cv::Mat & userData); // detect automatically if raw or compressed. If raw, the data is compressed too. /**
* Set user data. Detect automatically if raw or compressed. If raw, the data is
* compressed too. A matrix of type CV_8UC1 with 1 row is considered as compressed.
* If you have one dimension unsigned 8 bits raw data, make sure to transpose it
* (to have multiple rows instead of multiple columns) in order to be detected as
* not compressed.
*/
void setUserData(const cv::Mat & userData);
const cv::Mat & userDataRaw() const {return _userDataRaw;} const cv::Mat & userDataRaw() const {return _userDataRaw;}
const cv::Mat & userDataCompressed() const {return _userDataCompressed;} const cv::Mat & userDataCompressed() const {return _userDataCompressed;}
void setFeatures(const std::vector<cv::KeyPoint> & keypoints, const cv::Mat & descriptors) // detect automatically if raw or compressed. If raw, the data will be compressed.
{ void setOccupancyGrid(
_keypoints = keypoints; const cv::Mat & ground,
_descriptors = descriptors; const cv::Mat & obstacles,
} float cellSize,
const cv::Point3f & viewPoint);
// remove raw occupancy grids
void clearOccupancyGridRaw() {_groundCellsRaw = cv::Mat(); _obstacleCellsRaw = cv::Mat();}
const cv::Mat & gridGroundCellsRaw() const {return _groundCellsRaw;}
const cv::Mat & gridGroundCellsCompressed() const {return _groundCellsCompressed;}
const cv::Mat & gridObstacleCellsRaw() const {return _obstacleCellsRaw;}
const cv::Mat & gridObstacleCellsCompressed() const {return _obstacleCellsCompressed;}
float gridCellSize() const {return _cellSize;}
const cv::Point3f & gridViewPoint() const {return _viewPoint;}
void setFeatures(const std::vector<cv::KeyPoint> & keypoints, const std::vector<cv::Point3f> & keypoints3D, const cv::Mat & descriptors);
const std::vector<cv::KeyPoint> & keypoints() const {return _keypoints;} const std::vector<cv::KeyPoint> & keypoints() const {return _keypoints;}
const std::vector<cv::Point3f> & keypoints3D() const {return _keypoints3D;}
const cv::Mat & descriptors() const {return _descriptors;} const cv::Mat & descriptors() const {return _descriptors;}
void setGroundTruth(const Transform & pose) {groundTruth_ = pose;} void setGroundTruth(const Transform & pose) {groundTruth_ = pose;}
const Transform & groundTruth() const {return groundTruth_;} const Transform & groundTruth() const {return groundTruth_;}
long getMemoryUsed() const; // Return memory usage in Bytes
private: private:
int _id; int _id;
double _stamp; double _stamp;
int _laserScanMaxPts;
float _laserScanMaxRange;
cv::Mat _imageCompressed; // compressed image cv::Mat _imageCompressed; // compressed image
cv::Mat _depthOrRightCompressed; // compressed image cv::Mat _depthOrRightCompressed; // compressed image
@@ -211,12 +238,23 @@ private:
std::vector<CameraModel> _cameraModels; std::vector<CameraModel> _cameraModels;
StereoCameraModel _stereoCameraModel; StereoCameraModel _stereoCameraModel;
LaserScanInfo _laserScanInfo;
// user data // user data
cv::Mat _userDataCompressed; // compressed data cv::Mat _userDataCompressed; // compressed data
cv::Mat _userDataRaw; cv::Mat _userDataRaw;
// occupancy grid
cv::Mat _groundCellsCompressed;
cv::Mat _obstacleCellsCompressed;
cv::Mat _groundCellsRaw;
cv::Mat _obstacleCellsRaw;
float _cellSize;
cv::Point3f _viewPoint;
// features // features
std::vector<cv::KeyPoint> _keypoints; std::vector<cv::KeyPoint> _keypoints;
std::vector<cv::Point3f> _keypoints3D;
cv::Mat _descriptors; cv::Mat _descriptors;
Transform groundTruth_; Transform groundTruth_;

View File

@@ -1,5 +1,5 @@
/* /*
Copyright (c) 2010-2014, Mathieu Labbe - IntRoLab - Universite de Sherbrooke Copyright (c) 2010-2016, Mathieu Labbe - IntRoLab - Universite de Sherbrooke
All rights reserved. All rights reserved.
Redistribution and use in source and binary forms, with or without Redistribution and use in source and binary forms, with or without

View File

@@ -1,5 +1,5 @@
/* /*
Copyright (c) 2010-2014, Mathieu Labbe - IntRoLab - Universite de Sherbrooke Copyright (c) 2010-2016, Mathieu Labbe - IntRoLab - Universite de Sherbrooke
All rights reserved. All rights reserved.
Redistribution and use in source and binary forms, with or without Redistribution and use in source and binary forms, with or without
@@ -69,6 +69,8 @@ class RTABMAP_EXP Statistics
RTABMAP_STATS(Proximity, Time_detections,); RTABMAP_STATS(Proximity, Time_detections,);
RTABMAP_STATS(Proximity, Space_last_detection_id,); RTABMAP_STATS(Proximity, Space_last_detection_id,);
RTABMAP_STATS(Proximity, Space_paths,); RTABMAP_STATS(Proximity, Space_paths,);
RTABMAP_STATS(Proximity, Space_visual_paths_checked,);
RTABMAP_STATS(Proximity, Space_scan_paths_checked,);
RTABMAP_STATS(Proximity, Space_detections_added_visually,); RTABMAP_STATS(Proximity, Space_detections_added_visually,);
RTABMAP_STATS(Proximity, Space_detections_added_icp_only,); RTABMAP_STATS(Proximity, Space_detections_added_icp_only,);
@@ -92,6 +94,8 @@ class RTABMAP_EXP Statistics
RTABMAP_STATS(Memory, Rehearsal_merged,); RTABMAP_STATS(Memory, Rehearsal_merged,);
RTABMAP_STATS(Memory, Local_graph_size,); RTABMAP_STATS(Memory, Local_graph_size,);
RTABMAP_STATS(Memory, Small_movement,); RTABMAP_STATS(Memory, Small_movement,);
RTABMAP_STATS(Memory, Odometry_variance_ang,);
RTABMAP_STATS(Memory, Odometry_variance_lin,);
RTABMAP_STATS(Memory, Distance_travelled, m); RTABMAP_STATS(Memory, Distance_travelled, m);
RTABMAP_STATS(Timing, Memory_update, ms); RTABMAP_STATS(Timing, Memory_update, ms);
@@ -124,14 +128,19 @@ class RTABMAP_EXP Statistics
RTABMAP_STATS(TimingMem, Joining_dictionary_update, ms); RTABMAP_STATS(TimingMem, Joining_dictionary_update, ms);
RTABMAP_STATS(TimingMem, Add_new_words, ms); RTABMAP_STATS(TimingMem, Add_new_words, ms);
RTABMAP_STATS(TimingMem, Compressing_data, ms); RTABMAP_STATS(TimingMem, Compressing_data, ms);
RTABMAP_STATS(TimingMem, Post_decimation, ms);
RTABMAP_STATS(TimingMem, Scan_downsampling, ms);
RTABMAP_STATS(TimingMem, Scan_normals, ms);
RTABMAP_STATS(TimingMem, Occupancy_grid, ms);
RTABMAP_STATS(Keypoint, Dictionary_size, words); RTABMAP_STATS(Keypoint, Dictionary_size, words);
RTABMAP_STATS(Keypoint, Indexed_words, words); RTABMAP_STATS(Keypoint, Indexed_words, words);
RTABMAP_STATS(Keypoint, Index_memory_usage, KB); RTABMAP_STATS(Keypoint, Index_memory_usage, KB);
RTABMAP_STATS(Keypoint, Response_threshold,);
public: public:
static const std::map<std::string, float> & defaultData(); static const std::map<std::string, float> & defaultData();
static std::string serializeData(const std::map<std::string, float> & data);
static std::map<std::string, float> deserializeData(const std::string & data);
public: public:
Statistics(); Statistics();
@@ -145,6 +154,7 @@ public:
void setRefImageId(int refImageId) {_refImageId = refImageId;} void setRefImageId(int refImageId) {_refImageId = refImageId;}
void setLoopClosureId(int loopClosureId) {_loopClosureId = loopClosureId;} void setLoopClosureId(int loopClosureId) {_loopClosureId = loopClosureId;}
void setProximityDetectionId(int id) {_proximiyDetectionId = id;} void setProximityDetectionId(int id) {_proximiyDetectionId = id;}
void setStamp(double stamp) {_stamp = stamp;}
void setSignatures(const std::map<int, Signature> & signatures) {_signatures = signatures;} void setSignatures(const std::map<int, Signature> & signatures) {_signatures = signatures;}
@@ -165,6 +175,7 @@ public:
int refImageId() const {return _refImageId;} int refImageId() const {return _refImageId;}
int loopClosureId() const {return _loopClosureId;} int loopClosureId() const {return _loopClosureId;}
int proximityDetectionId() const {return _proximiyDetectionId;} int proximityDetectionId() const {return _proximiyDetectionId;}
double stamp() const {return _stamp;}
const std::map<int, Signature> & getSignatures() const {return _signatures;} const std::map<int, Signature> & getSignatures() const {return _signatures;}
@@ -188,6 +199,7 @@ private:
int _refImageId; int _refImageId;
int _loopClosureId; int _loopClosureId;
int _proximiyDetectionId; int _proximiyDetectionId;
double _stamp;
std::map<int, Signature> _signatures; std::map<int, Signature> _signatures;

View File

@@ -1,5 +1,5 @@
/* /*
Copyright (c) 2010-2014, Mathieu Labbe - IntRoLab - Universite de Sherbrooke Copyright (c) 2010-2016, Mathieu Labbe - IntRoLab - Universite de Sherbrooke
All rights reserved. All rights reserved.
Redistribution and use in source and binary forms, with or without Redistribution and use in source and binary forms, with or without

View File

@@ -1,5 +1,5 @@
/* /*
Copyright (c) 2010-2014, Mathieu Labbe - IntRoLab - Universite de Sherbrooke Copyright (c) 2010-2016, Mathieu Labbe - IntRoLab - Universite de Sherbrooke
All rights reserved. All rights reserved.
Redistribution and use in source and binary forms, with or without Redistribution and use in source and binary forms, with or without
@@ -35,7 +35,7 @@ namespace rtabmap {
class RTABMAP_EXP StereoCameraModel class RTABMAP_EXP StereoCameraModel
{ {
public: public:
StereoCameraModel() {} StereoCameraModel() : leftSuffix_("left"), rightSuffix_("right") {}
StereoCameraModel( StereoCameraModel(
const std::string & name, const std::string & name,
const cv::Size & imageSize1, const cv::Size & imageSize1,
@@ -87,7 +87,7 @@ public:
void initRectificationMap() {left_.initRectificationMap(); right_.initRectificationMap();} void initRectificationMap() {left_.initRectificationMap(); right_.initRectificationMap();}
void setName(const std::string & name); void setName(const std::string & name, const std::string & leftSuffix = "left", const std::string & rightSuffix = "right");
const std::string & name() const {return name_;} const std::string & name() const {return name_;}
// backward compatibility // backward compatibility
@@ -95,8 +95,9 @@ public:
bool load(const std::string & directory, const std::string & cameraName, bool ignoreStereoTransform = true); bool load(const std::string & directory, const std::string & cameraName, bool ignoreStereoTransform = true);
bool save(const std::string & directory, bool ignoreStereoTransform = true) const; bool save(const std::string & directory, bool ignoreStereoTransform = true) const;
bool saveStereoTransform(const std::string & directory) const;
double baseline() const {return right_.fx()!=0.0?-right_.Tx()/right_.fx():0.0;} double baseline() const {return right_.fx()!=0.0 && left_.fx() != 0.0 ? left_.Tx() / left_.fx() - right_.Tx()/right_.fx():0.0;}
float computeDepth(float disparity) const; float computeDepth(float disparity) const;
float computeDisparity(float depth) const; // m float computeDisparity(float depth) const; // m
@@ -108,6 +109,7 @@ public:
const cv::Mat & F() const {return F_;} //extrinsic fundamental matrix const cv::Mat & F() const {return F_;} //extrinsic fundamental matrix
void scale(double scale); void scale(double scale);
void roi(const cv::Rect & roi);
void setLocalTransform(const Transform & transform) {left_.setLocalTransform(transform);} void setLocalTransform(const Transform & transform) {left_.setLocalTransform(transform);}
const Transform & localTransform() const {return left_.localTransform();} const Transform & localTransform() const {return left_.localTransform();}
@@ -116,7 +118,12 @@ public:
const CameraModel & left() const {return left_;} const CameraModel & left() const {return left_;}
const CameraModel & right() const {return right_;} const CameraModel & right() const {return right_;}
const std::string & getLeftSuffix() const {return leftSuffix_;}
const std::string & getRightSuffix() const {return rightSuffix_;}
private: private:
std::string leftSuffix_;
std::string rightSuffix_;
CameraModel left_; CameraModel left_;
CameraModel right_; CameraModel right_;
std::string name_; std::string name_;

View File

@@ -1,5 +1,5 @@
/* /*
Copyright (c) 2010-2014, Mathieu Labbe - IntRoLab - Universite de Sherbrooke Copyright (c) 2010-2016, Mathieu Labbe - IntRoLab - Universite de Sherbrooke
All rights reserved. All rights reserved.
Redistribution and use in source and binary forms, with or without Redistribution and use in source and binary forms, with or without

View File

@@ -1,5 +1,5 @@
/* /*
Copyright (c) 2010-2014, Mathieu Labbe - IntRoLab - Universite de Sherbrooke Copyright (c) 2010-2016, Mathieu Labbe - IntRoLab - Universite de Sherbrooke
All rights reserved. All rights reserved.
Redistribution and use in source and binary forms, with or without Redistribution and use in source and binary forms, with or without
@@ -106,6 +106,7 @@ public:
void getTranslationAndEulerAngles(float & x, float & y, float & z, float & roll, float & pitch, float & yaw) const; void getTranslationAndEulerAngles(float & x, float & y, float & z, float & roll, float & pitch, float & yaw) const;
void getEulerAngles(float & roll, float & pitch, float & yaw) const; void getEulerAngles(float & roll, float & pitch, float & yaw) const;
void getTranslation(float & x, float & y, float & z) const; void getTranslation(float & x, float & y, float & z) const;
float getAngle(float x=1.0f, float y=0.0f, float z=0.0f) const;
float getNorm() const; float getNorm() const;
float getNormSquared() const; float getNormSquared() const;
float getDistance(const Transform & t) const; float getDistance(const Transform & t) const;

View File

@@ -1,5 +1,5 @@
/* /*
Copyright (c) 2010-2014, Mathieu Labbe - IntRoLab - Universite de Sherbrooke Copyright (c) 2010-2016, Mathieu Labbe - IntRoLab - Universite de Sherbrooke
All rights reserved. All rights reserved.
Redistribution and use in source and binary forms, with or without Redistribution and use in source and binary forms, with or without

View File

@@ -1,5 +1,5 @@
/* /*
Copyright (c) 2010-2014, Mathieu Labbe - IntRoLab - Universite de Sherbrooke Copyright (c) 2010-2016, Mathieu Labbe - IntRoLab - Universite de Sherbrooke
All rights reserved. All rights reserved.
Redistribution and use in source and binary forms, with or without Redistribution and use in source and binary forms, with or without

View File

@@ -1,5 +1,5 @@
/* /*
Copyright (c) 2010-2014, Mathieu Labbe - IntRoLab - Universite de Sherbrooke Copyright (c) 2010-2016, Mathieu Labbe - IntRoLab - Universite de Sherbrooke
All rights reserved. All rights reserved.
Redistribution and use in source and binary forms, with or without Redistribution and use in source and binary forms, with or without

View File

@@ -0,0 +1,130 @@
/*
Copyright (c) 2013, Alex Teichman and Stephen Miller (Stanford University)
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
* Neither the name of the <organization> nor the
names of its contributors may be used to endorse or promote products
derived from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL <COPYRIGHT HOLDER> BE LIABLE FOR ANY
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
RTAB-Map integration: Mathieu Labbe
*/
#ifndef DISCRETE_DEPTH_DISTORTION_MODEL_H
#define DISCRETE_DEPTH_DISTORTION_MODEL_H
#include <assert.h>
#include <vector>
#include <Eigen/Core>
#include <opencv2/opencv.hpp>
#include <rtabmap/utilite/UMutex.h>
#include "rtabmap/core/RtabmapExp.h" // DLL export/import defines
namespace clams
{
class RTABMAP_EXP DiscreteFrustum
{
public:
DiscreteFrustum(int smoothing = 1, double bin_depth = 1.0);
//! z value, not distance to origin.
//! thread-safe.
void addExample(double ground_truth, double measurement);
int index(double z) const;
void undistort(double* z) const;
void interpolatedUndistort(double* z) const;
void serialize(std::ostream& out, bool ascii) const;
void deserialize(std::istream& in, bool ascii);
protected:
double max_dist_;
int num_bins_;
double bin_depth_;
Eigen::VectorXf counts_;
Eigen::VectorXf total_numerators_;
Eigen::VectorXf total_denominators_;
Eigen::VectorXf multipliers_;
friend class DiscreteDepthDistortionModel;
};
class RTABMAP_EXP DiscreteDepthDistortionModel
{
public:
DiscreteDepthDistortionModel() :
width_(0),
height_(0),
bin_width_(0),
bin_height_(0),
bin_depth_(0),
num_bins_x_(0),
num_bins_y_(0),
training_samples_(0)
{}
virtual ~DiscreteDepthDistortionModel();
DiscreteDepthDistortionModel(int width, int height, int bin_width = 8, int bin_height = 6, double bin_depth = 2.0, int smoothing = 1);
DiscreteDepthDistortionModel(const DiscreteDepthDistortionModel& other);
DiscreteDepthDistortionModel& operator=(const DiscreteDepthDistortionModel& other);
void undistort(cv::Mat & depth) const;
//! Returns the number of training examples it used from this pair.
//! Thread-safe.
size_t accumulate(const cv::Mat& ground_truth, const cv::Mat& measurement);
void addExample(int v, int u, double ground_truth, double measurement);
void save(const std::string& path) const;
void load(const std::string& path);
void serialize(std::ostream& out, bool ascii) const;
void deserialize(std::istream& in, bool ascii);
cv::Mat visualize(const std::string& path = "") const;
int getWidth() const {return width_;}
int getHeight() const {return height_;}
size_t getTrainingSamples() const {return training_samples_;}
bool isValid() const
{
return !frustums_.empty();
}
protected:
//! Image width.
int width_;
//! Image height.
int height_;
//! Width of each bin in pixels.
int bin_width_;
//! Height of each bin in pixels.
int bin_height_;
//! Depth of each bin in meters.
double bin_depth_;
int num_bins_x_;
int num_bins_y_;
//! frustums_[y][x]
std::vector< std::vector<DiscreteFrustum*> > frustums_;
size_t training_samples_;
void deleteFrustums();
DiscreteFrustum& frustum(int y, int x);
const DiscreteFrustum& frustum(int y, int x) const;
UMutex mutex_;
};
} // namespace clams
#endif // DISCRETE_DEPTH_DISTORTION_MODEL_H

View File

@@ -0,0 +1,96 @@
/*
Copyright (c) 2013, Alex Teichman and Stephen Miller (Stanford University)
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
* Neither the name of the <organization> nor the
names of its contributors may be used to endorse or promote products
derived from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL <COPYRIGHT HOLDER> BE LIABLE FOR ANY
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
RTAB-Map integration: Mathieu Labbe
*/
#ifndef FRAME_PROJECTOR_H
#define FRAME_PROJECTOR_H
#include <pcl/point_cloud.h>
#include <pcl/point_types.h>
#include <opencv2/core/core.hpp>
#include <rtabmap/core/CameraModel.h>
#include "rtabmap/core/RtabmapExp.h" // DLL export/import defines
#define MAX_MULT 1.3
#define MIN_MULT 0.7
namespace clams
{
//! "Projective" point comes from the OpenNI terminology, and refers to (u, v, z), i.e.
//! pixel id and depth value. Here I've added color, too, so that this represents everything
//! that is known about a pixel in an RBGD camera.
class ProjectivePoint
{
public:
ProjectivePoint() :
u_(0),
v_(0),
z_(0.0f) {}
int u_;
int v_;
float z_; // in meters
};
//! This is essentially a pinhole camera model for an RGBD sensor, with
//! some extra functions added on for use during calibration.
class RTABMAP_EXP FrameProjector
{
public:
// For storing z values in meters. This is not Euclidean distance.
typedef std::vector< std::vector< std::vector<double> > > RangeIndex;
FrameProjector(const rtabmap::CameraModel & model);
RangeIndex cloudToRangeIndex(const pcl::PointCloud<pcl::PointXYZ>::Ptr & pcd) const;
//! transform is applied to the map, then projected into a depth index.
//! The best depth estimate from the map corresponding to the measurement depth frame
//! will be returned.
cv::Mat estimateMapDepth(
const pcl::PointCloud<pcl::PointXYZ>::Ptr & map,
const rtabmap::Transform & transform,
const cv::Mat & measurement,
double coneRadius = 0.02,
double coneStdevThresh = 0.03) const;
pcl::PointXYZ project(const ProjectivePoint& ppt) const;
ProjectivePoint reproject(const pcl::PointXYZ& pt) const;
protected:
bool coneFit(const cv::Size& imageSize, const RangeIndex& rindex,
int uc, int vc, double radius, double measurement_depth,
double* mean, double* stdev) const;
private:
rtabmap::CameraModel model_;
};
} // namespace clams
#endif // FRAME_PROJECTOR_H

View File

@@ -0,0 +1,52 @@
/*
Copyright (c) 2013, Alex Teichman and Stephen Miller (Stanford University)
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
* Neither the name of the <organization> nor the
names of its contributors may be used to endorse or promote products
derived from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL <COPYRIGHT HOLDER> BE LIABLE FOR ANY
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
RTAB-Map integration: Mathieu Labbe
*/
#ifndef SLAM_CALIBRATOR_H
#define SLAM_CALIBRATOR_H
#include <rtabmap/core/clams/discrete_depth_distortion_model.h>
#include <rtabmap/core/SensorData.h>
#include <pcl/point_cloud.h>
#include <pcl/point_types.h>
#include "rtabmap/core/RtabmapExp.h" // DLL export/import defines
namespace clams
{
DiscreteDepthDistortionModel RTABMAP_EXP calibrate(
const std::map<int, rtabmap::SensorData> & sequence,
const std::map<int, rtabmap::Transform> & trajectory,
const pcl::PointCloud<pcl::PointXYZ>::Ptr & map,
double coneRadius = 0.02,
double coneStdevThresh = 0.03);
}
#endif // SLAM_CALIBRATOR_H

View File

@@ -0,0 +1,163 @@
/*
Copyright (c) 2010-2016, Mathieu Labbe - IntRoLab - Universite de Sherbrooke
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
* Neither the name of the Universite de Sherbrooke nor the
names of its contributors may be used to endorse or promote products
derived from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef CORELIB_INCLUDE_RTABMAP_CORE_IMPL_OCCUPANCYGRID_HPP_
#define CORELIB_INCLUDE_RTABMAP_CORE_IMPL_OCCUPANCYGRID_HPP_
#include <rtabmap/core/util3d_mapping.h>
#include <rtabmap/core/util3d_transforms.h>
#include <rtabmap/utilite/ULogger.h>
namespace rtabmap {
template<typename PointT>
typename pcl::PointCloud<PointT>::Ptr OccupancyGrid::segmentCloud(
const typename pcl::PointCloud<PointT>::Ptr & cloudIn,
const pcl::IndicesPtr & indicesIn,
const Transform & pose,
const cv::Point3f & viewPoint,
pcl::IndicesPtr & groundIndices,
pcl::IndicesPtr & obstaclesIndices,
pcl::IndicesPtr * flatObstacles) const
{
typename pcl::PointCloud<PointT>::Ptr cloud(new pcl::PointCloud<PointT>);
// voxelize to grid cell size
cloud = util3d::voxelize(cloudIn, indicesIn, cellSize_);
pcl::IndicesPtr indices(new std::vector<int>);
indices->resize(cloud->size());
for(unsigned int i=0; i<indices->size(); ++i)
{
indices->at(i) = i;
}
// add pose rotation without yaw
float roll, pitch, yaw;
pose.getEulerAngles(roll, pitch, yaw);
UDEBUG("node.getPose()=%s projMapFrame_=%d", pose.prettyPrint().c_str(), projMapFrame_?1:0);
cloud = util3d::transformPointCloud(cloud, Transform(0,0, projMapFrame_?pose.z():0, roll, pitch, 0));
// filter footprint
if(footprintLength_ > 0.0f || footprintWidth_ > 0.0f || footprintHeight_ > 0.0f)
{
indices = util3d::cropBox(
cloud,
indices,
Eigen::Vector4f(
footprintLength_>0.0f?-footprintLength_/2.0f:std::numeric_limits<int>::min(),
footprintWidth_>0.0f&&footprintLength_>0.0f?-footprintWidth_/2.0f:std::numeric_limits<int>::min(),
0,
1),
Eigen::Vector4f(
footprintLength_>0.0f?footprintLength_/2.0f:std::numeric_limits<int>::max(),
footprintWidth_>0.0f&&footprintLength_>0.0f?footprintWidth_/2.0f:std::numeric_limits<int>::max(),
footprintHeight_>0.0f&&footprintLength_>0.0f&&footprintWidth_>0.0f?footprintHeight_:std::numeric_limits<int>::max(),
1),
Transform::getIdentity(),
true);
}
// filter ground/obstacles zone
if(minGroundHeight_ != 0.0f || maxObstacleHeight_ > 0.0f)
{
indices = util3d::passThrough(cloud, indices, "z",
minGroundHeight_!=0.0f?minGroundHeight_:std::numeric_limits<int>::min(),
maxObstacleHeight_>0.0f?maxObstacleHeight_:std::numeric_limits<int>::max());
UDEBUG("indices after max obstacles height filtering = %d", (int)indices->size());
}
if(indices->size())
{
if(normalsSegmentation_)
{
UDEBUG("normalKSearch=%d", normalKSearch_);
UDEBUG("maxGroundAngle=%f", maxGroundAngle_);
UDEBUG("Cluster radius=%f", clusterRadius_);
UDEBUG("flatObstaclesDetected=%d", flatObstaclesDetected_?1:0);
UDEBUG("maxGroundHeight=%f", maxGroundHeight_?1:0);
util3d::segmentObstaclesFromGround<PointT>(
cloud,
indices,
groundIndices,
obstaclesIndices,
normalKSearch_,
maxGroundAngle_,
clusterRadius_,
minClusterSize_,
flatObstaclesDetected_,
maxGroundHeight_,
flatObstacles,
Eigen::Vector4f(viewPoint.x, viewPoint.y, viewPoint.z+(projMapFrame_?pose.z():0), 1));
UDEBUG("viewPoint=%f,%f,%f", viewPoint.x, viewPoint.y, viewPoint.z+(projMapFrame_?pose.z():0));
//UWARN("Saving ground.pcd and obstacles.pcd");
//pcl::io::savePCDFile("ground.pcd", *cloud, *groundIndices);
//pcl::io::savePCDFile("obstacles.pcd", *cloud, *obstaclesIndices);
}
else
{
UDEBUG("");
// passthrough filter
groundIndices = rtabmap::util3d::passThrough(cloud, indices, "z", minGroundHeight_<0.0f?minGroundHeight_:std::numeric_limits<int>::min(), maxGroundHeight_);
obstaclesIndices = rtabmap::util3d::extractIndices(cloud, groundIndices, true);
}
UDEBUG("groundIndices=%d obstaclesIndices=%d", (int)groundIndices->size(), (int)obstaclesIndices->size());
// Do radius filtering after voxel filtering ( a lot faster)
if(noiseFilteringRadius_ > 0.0 && noiseFilteringMinNeighbors_ > 0)
{
UDEBUG("");
if(groundIndices->size())
{
groundIndices = rtabmap::util3d::radiusFiltering(cloud, groundIndices, noiseFilteringRadius_, noiseFilteringMinNeighbors_);
}
if(obstaclesIndices->size())
{
obstaclesIndices = rtabmap::util3d::radiusFiltering(cloud, obstaclesIndices, noiseFilteringRadius_, noiseFilteringMinNeighbors_);
}
if(flatObstacles && (*flatObstacles)->size())
{
*flatObstacles = rtabmap::util3d::radiusFiltering(cloud, *flatObstacles, noiseFilteringRadius_, noiseFilteringMinNeighbors_);
}
if(groundIndices->empty() && obstaclesIndices->empty())
{
UWARN("Cloud (with %d points) is empty after noise "
"filtering. Occupancy grid cannot be "
"created.",
(int)cloud->size());
}
}
}
return cloud;
}
}
#endif /* CORELIB_INCLUDE_RTABMAP_CORE_IMPL_OCCUPANCYGRID_HPP_ */

View File

@@ -1,9 +1,29 @@
/* /*
* util3d_mapping.hpp Copyright (c) 2010-2016, Mathieu Labbe - IntRoLab - Universite de Sherbrooke
* All rights reserved.
* Created on: 2015-05-13
* Author: mathieu Redistribution and use in source and binary forms, with or without
*/ modification, are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
* Neither the name of the Universite de Sherbrooke nor the
names of its contributors may be used to endorse or promote products
derived from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef UTIL3D_MAPPING_HPP_ #ifndef UTIL3D_MAPPING_HPP_
#define UTIL3D_MAPPING_HPP_ #define UTIL3D_MAPPING_HPP_
@@ -17,6 +37,19 @@
namespace rtabmap{ namespace rtabmap{
namespace util3d{ namespace util3d{
template<typename PointT>
typename pcl::PointCloud<PointT>::Ptr projectCloudOnXYPlane(
const typename pcl::PointCloud<PointT> & cloud)
{
typename pcl::PointCloud<PointT>::Ptr output(new pcl::PointCloud<PointT>);
*output = cloud;
for(unsigned int i=0; i<output->size(); ++i)
{
output->at(i).z = 0;
}
return output;
}
template<typename PointT> template<typename PointT>
void segmentObstaclesFromGround( void segmentObstaclesFromGround(
const typename pcl::PointCloud<PointT>::Ptr & cloud, const typename pcl::PointCloud<PointT>::Ptr & cloud,
@@ -29,7 +62,8 @@ void segmentObstaclesFromGround(
int minClusterSize, int minClusterSize,
bool segmentFlatObstacles, bool segmentFlatObstacles,
float maxGroundHeight, float maxGroundHeight,
pcl::IndicesPtr * flatObstacles) pcl::IndicesPtr * flatObstacles,
const Eigen::Vector4f & viewPoint)
{ {
ground.reset(new std::vector<int>); ground.reset(new std::vector<int>);
obstacles.reset(new std::vector<int>); obstacles.reset(new std::vector<int>);
@@ -47,9 +81,11 @@ void segmentObstaclesFromGround(
groundNormalAngle, groundNormalAngle,
Eigen::Vector4f(0,0,1,0), Eigen::Vector4f(0,0,1,0),
normalKSearch, normalKSearch,
Eigen::Vector4f(0,0,100,0)); viewPoint);
if(segmentFlatObstacles) UDEBUG("cloud=%d, indices=%d flatSurfaces=%d", (int)cloud->size(), (int)indices->size(), (int)flatSurfaces->size());
if(segmentFlatObstacles && flatSurfaces->size())
{ {
int biggestFlatSurfaceIndex; int biggestFlatSurfaceIndex;
std::vector<pcl::IndicesPtr> clusteredFlatSurfaces = extractClusters( std::vector<pcl::IndicesPtr> clusteredFlatSurfaces = extractClusters(
@@ -59,7 +95,7 @@ void segmentObstaclesFromGround(
minClusterSize, minClusterSize,
std::numeric_limits<int>::max(), std::numeric_limits<int>::max(),
&biggestFlatSurfaceIndex); &biggestFlatSurfaceIndex);
UDEBUG("clusteredFlatSurfaces=%d", (int)clusteredFlatSurfaces.size());
// cluster all surfaces for which the centroid is in the Z-range of the bigger surface // cluster all surfaces for which the centroid is in the Z-range of the bigger surface
if(clusteredFlatSurfaces.size()) if(clusteredFlatSurfaces.size())
@@ -74,7 +110,7 @@ void segmentObstaclesFromGround(
{ {
if((int)i!=biggestFlatSurfaceIndex) if((int)i!=biggestFlatSurfaceIndex)
{ {
Eigen::Vector4f centroid; Eigen::Vector4f centroid(0,0,0,1);
pcl::compute3DCentroid(*cloud, *clusteredFlatSurfaces.at(i), centroid); pcl::compute3DCentroid(*cloud, *clusteredFlatSurfaces.at(i), centroid);
if(centroid[2] >= min[2]-0.01 && if(centroid[2] >= min[2]-0.01 &&
(centroid[2] <= max[2]+0.01 || (maxGroundHeight>0 && centroid[2] <= maxGroundHeight+0.01))) // epsilon (centroid[2] <= max[2]+0.01 || (maxGroundHeight>0 && centroid[2] <= maxGroundHeight+0.01))) // epsilon
@@ -104,10 +140,18 @@ void segmentObstaclesFromGround(
ground = flatSurfaces; ground = flatSurfaces;
} }
UDEBUG("ground=%d", (int)ground->size());
if(ground->size() != cloud->size()) if(ground->size() != cloud->size())
{ {
// Remove ground // Remove ground
pcl::IndicesPtr otherStuffIndices = util3d::extractIndices(cloud, ground, true); pcl::IndicesPtr notObstacles = ground;
if(indices->size())
{
notObstacles = util3d::extractIndices(cloud, indices, true);
notObstacles = util3d::concatenate(notObstacles, ground);
}
pcl::IndicesPtr otherStuffIndices = util3d::extractIndices(cloud, notObstacles, true);
// If ground height is set, remove obstacles under it // If ground height is set, remove obstacles under it
if(maxGroundHeight > 0.0f) if(maxGroundHeight > 0.0f)
@@ -116,14 +160,17 @@ void segmentObstaclesFromGround(
} }
//Cluster remaining stuff (obstacles) //Cluster remaining stuff (obstacles)
std::vector<pcl::IndicesPtr> clusteredObstaclesSurfaces = util3d::extractClusters( if(otherStuffIndices->size())
cloud, {
otherStuffIndices, std::vector<pcl::IndicesPtr> clusteredObstaclesSurfaces = util3d::extractClusters(
clusterRadius, cloud,
minClusterSize); otherStuffIndices,
clusterRadius,
minClusterSize);
// merge indices // merge indices
obstacles = util3d::concatenate(clusteredObstaclesSurfaces); obstacles = util3d::concatenate(clusteredObstaclesSurfaces);
}
} }
} }
} }
@@ -139,7 +186,8 @@ void segmentObstaclesFromGround(
int minClusterSize, int minClusterSize,
bool segmentFlatObstacles, bool segmentFlatObstacles,
float maxGroundHeight, float maxGroundHeight,
pcl::IndicesPtr * flatObstacles) pcl::IndicesPtr * flatObstacles,
const Eigen::Vector4f & viewPoint)
{ {
pcl::IndicesPtr indices(new std::vector<int>); pcl::IndicesPtr indices(new std::vector<int>);
segmentObstaclesFromGround<PointT>( segmentObstaclesFromGround<PointT>(
@@ -153,7 +201,81 @@ void segmentObstaclesFromGround(
minClusterSize, minClusterSize,
segmentFlatObstacles, segmentFlatObstacles,
maxGroundHeight, maxGroundHeight,
flatObstacles); flatObstacles,
viewPoint);
}
template<typename PointT>
void occupancy2DFromGroundObstacles(
const typename pcl::PointCloud<PointT>::Ptr & cloud,
const pcl::IndicesPtr & groundIndices,
const pcl::IndicesPtr & obstaclesIndices,
cv::Mat & ground,
cv::Mat & obstacles,
float cellSize)
{
typename pcl::PointCloud<PointT>::Ptr groundCloud(new pcl::PointCloud<PointT>);
typename pcl::PointCloud<PointT>::Ptr obstaclesCloud(new pcl::PointCloud<PointT>);
if(groundIndices->size())
{
pcl::copyPointCloud(*cloud, *groundIndices, *groundCloud);
}
if(obstaclesIndices->size())
{
pcl::copyPointCloud(*cloud, *obstaclesIndices, *obstaclesCloud);
}
occupancy2DFromGroundObstacles<PointT>(
groundCloud,
obstaclesCloud,
ground,
obstacles,
cellSize);
}
template<typename PointT>
void occupancy2DFromGroundObstacles(
const typename pcl::PointCloud<PointT>::Ptr & groundCloud,
const typename pcl::PointCloud<PointT>::Ptr & obstaclesCloud,
cv::Mat & ground,
cv::Mat & obstacles,
float cellSize)
{
ground = cv::Mat();
if(groundCloud->size())
{
//project on XY plane
typename pcl::PointCloud<PointT>::Ptr groundCloudProjected;
groundCloudProjected = util3d::projectCloudOnXYPlane(*groundCloud);
//voxelize to grid cell size
groundCloudProjected = util3d::voxelize(groundCloudProjected, cellSize);
ground = cv::Mat(1, (int)groundCloudProjected->size(), CV_32FC2);
for(unsigned int i=0;i<groundCloudProjected->size(); ++i)
{
ground.at<cv::Vec2f>(i)[0] = groundCloudProjected->at(i).x;
ground.at<cv::Vec2f>(i)[1] = groundCloudProjected->at(i).y;
}
}
obstacles = cv::Mat();
if(obstaclesCloud->size())
{
//project on XY plane
typename pcl::PointCloud<PointT>::Ptr obstaclesCloudProjected;
obstaclesCloudProjected = util3d::projectCloudOnXYPlane(*obstaclesCloud);
//voxelize to grid cell size
obstaclesCloudProjected = util3d::voxelize(obstaclesCloudProjected, cellSize);
obstacles = cv::Mat(1, (int)obstaclesCloudProjected->size(), CV_32FC2);
for(unsigned int i=0;i<obstaclesCloudProjected->size(); ++i)
{
obstacles.at<cv::Vec2f>(i)[0] = obstaclesCloudProjected->at(i).x;
obstacles.at<cv::Vec2f>(i)[1] = obstaclesCloudProjected->at(i).y;
}
}
} }
template<typename PointT> template<typename PointT>
@@ -186,48 +308,13 @@ void occupancy2DFromCloud3D(
segmentFlatObstacles, segmentFlatObstacles,
maxGroundHeight); maxGroundHeight);
pcl::PointCloud<pcl::PointXYZ>::Ptr groundCloud(new pcl::PointCloud<pcl::PointXYZ>); occupancy2DFromGroundObstacles<PointT>(
pcl::PointCloud<pcl::PointXYZ>::Ptr obstaclesCloud(new pcl::PointCloud<pcl::PointXYZ>); cloud,
groundIndices,
if(groundIndices->size()) obstaclesIndices,
{ ground,
pcl::copyPointCloud(*cloud, *groundIndices, *groundCloud); obstacles,
//project on XY plane cellSize);
util3d::projectCloudOnXYPlane(groundCloud);
//voxelize to grid cell size
groundCloud = util3d::voxelize(groundCloud, cellSize);
}
if(obstaclesIndices->size())
{
pcl::copyPointCloud(*cloud, *obstaclesIndices, *obstaclesCloud);
//project on XY plane
util3d::projectCloudOnXYPlane(obstaclesCloud);
//voxelize to grid cell size
obstaclesCloud = util3d::voxelize(obstaclesCloud, cellSize);
}
ground = cv::Mat();
if(groundCloud->size())
{
ground = cv::Mat((int)groundCloud->size(), 1, CV_32FC2);
for(unsigned int i=0;i<groundCloud->size(); ++i)
{
ground.at<cv::Vec2f>(i)[0] = groundCloud->at(i).x;
ground.at<cv::Vec2f>(i)[1] = groundCloud->at(i).y;
}
}
obstacles = cv::Mat();
if(obstaclesCloud->size())
{
obstacles = cv::Mat((int)obstaclesCloud->size(), 1, CV_32FC2);
for(unsigned int i=0;i<obstaclesCloud->size(); ++i)
{
obstacles.at<cv::Vec2f>(i)[0] = obstaclesCloud->at(i).x;
obstacles.at<cv::Vec2f>(i)[1] = obstaclesCloud->at(i).y;
}
}
} }
template<typename PointT> template<typename PointT>

View File

@@ -0,0 +1,50 @@
/*
* util3d_surface.hpp
*
* Created on: Sep 3, 2016
* Author: mathieu
*/
#ifndef CORELIB_INCLUDE_RTABMAP_CORE_IMPL_UTIL3D_SURFACE_HPP_
#define CORELIB_INCLUDE_RTABMAP_CORE_IMPL_UTIL3D_SURFACE_HPP_
namespace rtabmap {
namespace util3d {
template<typename pointT>
std::vector<pcl::Vertices> normalizePolygonsSide(
const typename pcl::PointCloud<pointT> & cloud,
const std::vector<pcl::Vertices> & polygons,
const pcl::PointXYZ & viewPoint)
{
std::vector<pcl::Vertices> output(polygons.size());
for(unsigned int i=0; i<polygons.size(); ++i)
{
pcl::Vertices polygon = polygons[i];
Eigen::Vector3f v1 = cloud.at(polygon.vertices[1]).getVector3fMap() - cloud.at(polygon.vertices[0]).getVector3fMap();
Eigen::Vector3f v2 = cloud.at(polygon.vertices[2]).getVector3fMap() - cloud.at(polygon.vertices[0]).getVector3fMap();
Eigen::Vector3f n = (v1.cross(v2)).normalized();
Eigen::Vector3f p = Eigen::Vector3f(viewPoint.x, viewPoint.y, viewPoint.z) - cloud.at(polygon.vertices[1]).getVector3fMap();
float result = n.dot(p);
if(result < 0)
{
//reverse vertices order
int tmp = polygon.vertices[0];
polygon.vertices[0] = polygon.vertices[2];
polygon.vertices[2] = tmp;
}
output[i] = polygon;
}
return output;
}
}
}
#endif /* CORELIB_INCLUDE_RTABMAP_CORE_IMPL_UTIL3D_SURFACE_HPP_ */

View File

@@ -1,5 +1,5 @@
/* /*
Copyright (c) 2010-2014, Mathieu Labbe - IntRoLab - Universite de Sherbrooke Copyright (c) 2010-2016, Mathieu Labbe - IntRoLab - Universite de Sherbrooke
All rights reserved. All rights reserved.
Redistribution and use in source and binary forms, with or without Redistribution and use in source and binary forms, with or without
@@ -109,6 +109,11 @@ float RTABMAP_EXP getDepth(
float maxZError = 0.02f, float maxZError = 0.02f,
bool estWithNeighborsIfNull = false); bool estWithNeighborsIfNull = false);
cv::Rect RTABMAP_EXP computeRoi(const cv::Mat & image, const std::string & roiRatios);
cv::Rect RTABMAP_EXP computeRoi(const cv::Size & imageSize, const std::string & roiRatios);
cv::Rect RTABMAP_EXP computeRoi(const cv::Mat & image, const std::vector<float> & roiRatios);
cv::Rect RTABMAP_EXP computeRoi(const cv::Size & imageSize, const std::vector<float> & roiRatios);
cv::Mat RTABMAP_EXP decimate(const cv::Mat & image, int d); cv::Mat RTABMAP_EXP decimate(const cv::Mat & image, int d);
cv::Mat RTABMAP_EXP interpolate(const cv::Mat & image, int factor, float depthErrorRatio = 0.02f); cv::Mat RTABMAP_EXP interpolate(const cv::Mat & image, int factor, float depthErrorRatio = 0.02f);
@@ -116,6 +121,7 @@ cv::Mat RTABMAP_EXP interpolate(const cv::Mat & image, int factor, float depthEr
cv::Mat RTABMAP_EXP registerDepth( cv::Mat RTABMAP_EXP registerDepth(
const cv::Mat & depth, const cv::Mat & depth,
const cv::Mat & depthK, const cv::Mat & depthK,
const cv::Size & colorSize,
const cv::Mat & colorK, const cv::Mat & colorK,
const rtabmap::Transform & transform); const rtabmap::Transform & transform);
@@ -130,6 +136,12 @@ void RTABMAP_EXP fillRegisteredDepthHoles(
bool horizontal, bool horizontal,
bool fillDoubleHoles = false); bool fillDoubleHoles = false);
cv::Mat RTABMAP_EXP fastBilateralFiltering(
const cv::Mat & depth,
float sigmaS = 15.0f,
float sigmaR = 0.05f,
bool earlyDivision = false);
} // namespace util3d } // namespace util3d
} // namespace rtabmap } // namespace rtabmap

View File

@@ -1,5 +1,5 @@
/* /*
Copyright (c) 2010-2014, Mathieu Labbe - IntRoLab - Universite de Sherbrooke Copyright (c) 2010-2016, Mathieu Labbe - IntRoLab - Universite de Sherbrooke
All rights reserved. All rights reserved.
Redistribution and use in source and binary forms, with or without Redistribution and use in source and binary forms, with or without
@@ -74,16 +74,23 @@ pcl::PointXYZ RTABMAP_EXP projectDepthTo3D(
bool smoothing, bool smoothing,
float maxZError = 0.02f); float maxZError = 0.02f);
pcl::PointCloud<pcl::PointXYZ>::Ptr RTABMAP_EXP cloudFromDepth( RTABMAP_DEPRECATED (pcl::PointCloud<pcl::PointXYZ>::Ptr RTABMAP_EXP cloudFromDepth(
const cv::Mat & imageDepth, const cv::Mat & imageDepth,
float cx, float cy, float cx, float cy,
float fx, float fy, float fx, float fy,
int decimation = 1, int decimation = 1,
float maxDepth = 0.0f, float maxDepth = 0.0f,
float minDepth = 0.0f, float minDepth = 0.0f,
std::vector<int> * validIndices = 0), "Use cloudFromDepth with CameraModel interface.");
pcl::PointCloud<pcl::PointXYZ>::Ptr RTABMAP_EXP cloudFromDepth(
const cv::Mat & imageDepth,
const CameraModel & model,
int decimation = 1,
float maxDepth = 0.0f,
float minDepth = 0.0f,
std::vector<int> * validIndices = 0); std::vector<int> * validIndices = 0);
pcl::PointCloud<pcl::PointXYZRGB>::Ptr RTABMAP_EXP cloudFromDepthRGB( RTABMAP_DEPRECATED (pcl::PointCloud<pcl::PointXYZRGB>::Ptr RTABMAP_EXP cloudFromDepthRGB(
const cv::Mat & imageRgb, const cv::Mat & imageRgb,
const cv::Mat & imageDepth, const cv::Mat & imageDepth,
float cx, float cy, float cx, float cy,
@@ -91,6 +98,14 @@ pcl::PointCloud<pcl::PointXYZRGB>::Ptr RTABMAP_EXP cloudFromDepthRGB(
int decimation = 1, int decimation = 1,
float maxDepth = 0.0f, float maxDepth = 0.0f,
float minDepth = 0.0f, float minDepth = 0.0f,
std::vector<int> * validIndices = 0), "Use cloudFromDepthRGB with CameraModel interface.");
pcl::PointCloud<pcl::PointXYZRGB>::Ptr RTABMAP_EXP cloudFromDepthRGB(
const cv::Mat & imageRgb,
const cv::Mat & imageDepth,
const CameraModel & model,
int decimation = 1,
float maxDepth = 0.0f,
float minDepth = 0.0f,
std::vector<int> * validIndices = 0); std::vector<int> * validIndices = 0);
pcl::PointCloud<pcl::PointXYZ>::Ptr RTABMAP_EXP cloudFromDisparity( pcl::PointCloud<pcl::PointXYZ>::Ptr RTABMAP_EXP cloudFromDisparity(
@@ -126,7 +141,8 @@ pcl::PointCloud<pcl::PointXYZ>::Ptr RTABMAP_EXP cloudFromSensorData(
float maxDepth = 0.0f, float maxDepth = 0.0f,
float minDepth = 0.0f, float minDepth = 0.0f,
std::vector<int> * validIndices = 0, std::vector<int> * validIndices = 0,
const ParametersMap & parameters = ParametersMap()); const ParametersMap & stereoParameters = ParametersMap(),
const std::vector<float> & roiRatios = std::vector<float>()); // ignored for stereo
/** /**
* Create an RGB cloud from the images contained in SensorData. If there is only one camera, * Create an RGB cloud from the images contained in SensorData. If there is only one camera,
@@ -139,6 +155,7 @@ pcl::PointCloud<pcl::PointXYZ>::Ptr RTABMAP_EXP cloudFromSensorData(
* @param maxDepth, maximum depth of the projected points (farther points are set to null in case of an organized cloud). * @param maxDepth, maximum depth of the projected points (farther points are set to null in case of an organized cloud).
* @param minDepth, minimum depth of the projected points (closer points are set to null in case of an organized cloud). * @param minDepth, minimum depth of the projected points (closer points are set to null in case of an organized cloud).
* @param validIndices, the indices of valid points in the cloud * @param validIndices, the indices of valid points in the cloud
* @param roiRatios, [left, right, top, bottom] region of interest (in ratios) of the image projected.
* @return a RGB cloud. * @return a RGB cloud.
*/ */
pcl::PointCloud<pcl::PointXYZRGB>::Ptr RTABMAP_EXP cloudRGBFromSensorData( pcl::PointCloud<pcl::PointXYZRGB>::Ptr RTABMAP_EXP cloudRGBFromSensorData(
@@ -147,7 +164,8 @@ pcl::PointCloud<pcl::PointXYZRGB>::Ptr RTABMAP_EXP cloudRGBFromSensorData(
float maxDepth = 0.0f, float maxDepth = 0.0f,
float minDepth = 0.0f, float minDepth = 0.0f,
std::vector<int> * validIndices = 0, std::vector<int> * validIndices = 0,
const ParametersMap & parameters = ParametersMap()); const ParametersMap & stereoParameters = ParametersMap(),
const std::vector<float> & roiRatios = std::vector<float>()); // ignored for stereo
pcl::PointCloud<pcl::PointXYZ> RTABMAP_EXP laserScanFromDepthImage( pcl::PointCloud<pcl::PointXYZ> RTABMAP_EXP laserScanFromDepthImage(
const cv::Mat & depthImage, const cv::Mat & depthImage,
@@ -158,17 +176,35 @@ pcl::PointCloud<pcl::PointXYZ> RTABMAP_EXP laserScanFromDepthImage(
float maxDepth = 0, float maxDepth = 0,
float minDepth = 0, float minDepth = 0,
const Transform & localTransform = Transform::getIdentity()); const Transform & localTransform = Transform::getIdentity());
pcl::PointCloud<pcl::PointXYZ> RTABMAP_EXP laserScanFromDepthImages(
const cv::Mat & depthImages,
const std::vector<CameraModel> & cameraModels,
float maxDepth,
float minDepth);
// return CV_32FC3 // return CV_32FC3
cv::Mat RTABMAP_EXP laserScanFromPointCloud(const pcl::PointCloud<pcl::PointXYZ> & cloud, const Transform & transform = Transform()); cv::Mat RTABMAP_EXP laserScanFromPointCloud(const pcl::PointCloud<pcl::PointXYZ> & cloud, const Transform & transform = Transform());
// return CV_32FC6 // return CV_32FC6
cv::Mat RTABMAP_EXP laserScanFromPointCloud(const pcl::PointCloud<pcl::PointNormal> & cloud, const Transform & transform = Transform()); cv::Mat RTABMAP_EXP laserScanFromPointCloud(const pcl::PointCloud<pcl::PointNormal> & cloud, const Transform & transform = Transform());
cv::Mat RTABMAP_EXP laserScanFromPointCloud(const pcl::PointCloud<pcl::PointXYZ> & cloud, const pcl::PointCloud<pcl::Normal> & normals, const Transform & transform = Transform());
// return CV_32FC4
cv::Mat RTABMAP_EXP laserScanFromPointCloud(const pcl::PointCloud<pcl::PointXYZRGB> & cloud, const Transform & transform = Transform());
// return CV_32FC2 // return CV_32FC2
cv::Mat RTABMAP_EXP laserScan2dFromPointCloud(const pcl::PointCloud<pcl::PointXYZ> & cloud, const Transform & transform = Transform()); cv::Mat RTABMAP_EXP laserScan2dFromPointCloud(const pcl::PointCloud<pcl::PointXYZ> & cloud, const Transform & transform = Transform());
// For laserScan of type CV_32FC2, z is set to null. // For laserScan of type CV_32FC2, z is set to null.
pcl::PointCloud<pcl::PointXYZ>::Ptr RTABMAP_EXP laserScanToPointCloud(const cv::Mat & laserScan, const Transform & transform = Transform()); pcl::PointCloud<pcl::PointXYZ>::Ptr RTABMAP_EXP laserScanToPointCloud(const cv::Mat & laserScan, const Transform & transform = Transform());
// For laserScan of type CV_32FC2 or CV_32FC3, normals are set to null. // For laserScan of type CV_32FC2, CV_32FC3 and CV_32FC4, normals are set to null.
pcl::PointCloud<pcl::PointNormal>::Ptr RTABMAP_EXP laserScanToPointCloudNormal(const cv::Mat & laserScan, const Transform & transform = Transform()); pcl::PointCloud<pcl::PointNormal>::Ptr RTABMAP_EXP laserScanToPointCloudNormal(const cv::Mat & laserScan, const Transform & transform = Transform());
// For laserScan of type CV_32FC2, CV_32FC3 and CV_32FC6, rgb is set to default r,g,b parameters.
pcl::PointCloud<pcl::PointXYZRGB>::Ptr RTABMAP_EXP laserScanToPointCloudRGB(const cv::Mat & laserScan, const Transform & transform = Transform(), unsigned char r = 255, unsigned char g = 255, unsigned char b = 255);
// For laserScan of type CV_32FC2, z is set to null.
pcl::PointXYZ RTABMAP_EXP laserScanToPoint(const cv::Mat & laserScan, int index);
// For laserScan of type CV_32FC2, CV_32FC3 and CV_32FC4, normals are set to null.
pcl::PointNormal RTABMAP_EXP laserScanToPointNormal(const cv::Mat & laserScan, int index);
// For laserScan of type CV_32FC2, CV_32FC3 and CV_32FC6, rgb is set to default r,g,b parameters.
pcl::PointXYZRGB RTABMAP_EXP laserScanToPointRGB(const cv::Mat & laserScan, int index, unsigned char r = 255, unsigned char g = 255, unsigned char b = 255);
cv::Point3f RTABMAP_EXP projectDisparityTo3D( cv::Point3f RTABMAP_EXP projectDisparityTo3D(
const cv::Point2f & pt, const cv::Point2f & pt,

View File

@@ -1,5 +1,5 @@
/* /*
Copyright (c) 2010-2014, Mathieu Labbe - IntRoLab - Universite de Sherbrooke Copyright (c) 2010-2016, Mathieu Labbe - IntRoLab - Universite de Sherbrooke
All rights reserved. All rights reserved.
Redistribution and use in source and binary forms, with or without Redistribution and use in source and binary forms, with or without

View File

@@ -1,5 +1,5 @@
/* /*
Copyright (c) 2010-2014, Mathieu Labbe - IntRoLab - Universite de Sherbrooke Copyright (c) 2010-2016, Mathieu Labbe - IntRoLab - Universite de Sherbrooke
All rights reserved. All rights reserved.
Redistribution and use in source and binary forms, with or without Redistribution and use in source and binary forms, with or without

View File

@@ -1,5 +1,5 @@
/* /*
Copyright (c) 2010-2014, Mathieu Labbe - IntRoLab - Universite de Sherbrooke Copyright (c) 2010-2016, Mathieu Labbe - IntRoLab - Universite de Sherbrooke
All rights reserved. All rights reserved.
Redistribution and use in source and binary forms, with or without Redistribution and use in source and binary forms, with or without
@@ -34,6 +34,7 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include <pcl/point_cloud.h> #include <pcl/point_cloud.h>
#include <pcl/point_types.h> #include <pcl/point_types.h>
#include <pcl/pcl_base.h> #include <pcl/pcl_base.h>
#include <pcl/ModelCoefficients.h>
namespace rtabmap namespace rtabmap
{ {
@@ -135,6 +136,33 @@ pcl::PointCloud<pcl::PointXYZRGB>::Ptr RTABMAP_EXP passThrough(
float max, float max,
bool negative = false); bool negative = false);
pcl::IndicesPtr RTABMAP_EXP cropBox(
const pcl::PointCloud<pcl::PointXYZ>::Ptr & cloud,
const pcl::IndicesPtr & indices,
const Eigen::Vector4f & min,
const Eigen::Vector4f & max,
const Transform & transform = Transform::getIdentity(),
bool negative = false);
pcl::IndicesPtr RTABMAP_EXP cropBox(
const pcl::PointCloud<pcl::PointXYZRGB>::Ptr & cloud,
const pcl::IndicesPtr & indices,
const Eigen::Vector4f & min,
const Eigen::Vector4f & max,
const Transform & transform = Transform::getIdentity(),
bool negative = false);
pcl::PointCloud<pcl::PointXYZ>::Ptr RTABMAP_EXP cropBox(
const pcl::PointCloud<pcl::PointXYZ>::Ptr & cloud,
const Eigen::Vector4f & min,
const Eigen::Vector4f & max,
const Transform & transform = Transform::getIdentity(),
bool negative = false);
pcl::PointCloud<pcl::PointXYZRGB>::Ptr RTABMAP_EXP cropBox(
const pcl::PointCloud<pcl::PointXYZRGB>::Ptr & cloud,
const Eigen::Vector4f & min,
const Eigen::Vector4f & max,
const Transform & transform = Transform::getIdentity(),
bool negative = false);
//Note: This assumes a coordinate system where X is forward, * Y is up, and Z is right. //Note: This assumes a coordinate system where X is forward, * Y is up, and Z is right.
pcl::IndicesPtr RTABMAP_EXP frustumFiltering( pcl::IndicesPtr RTABMAP_EXP frustumFiltering(
const pcl::PointCloud<pcl::PointXYZ>::Ptr & cloud, const pcl::PointCloud<pcl::PointXYZ>::Ptr & cloud,
@@ -383,7 +411,6 @@ pcl::IndicesPtr RTABMAP_EXP normalFiltering(
* @param viewpoint from which viewpoint the normals should be estimated (see pcl::NormalEstimation). * @param viewpoint from which viewpoint the normals should be estimated (see pcl::NormalEstimation).
* @return the indices of the points which respect the normal constraint. * @return the indices of the points which respect the normal constraint.
*/ */
pcl::IndicesPtr RTABMAP_EXP normalFiltering( pcl::IndicesPtr RTABMAP_EXP normalFiltering(
const pcl::PointCloud<pcl::PointXYZ>::Ptr & cloud, const pcl::PointCloud<pcl::PointXYZ>::Ptr & cloud,
const pcl::IndicesPtr & indices, const pcl::IndicesPtr & indices,
@@ -485,6 +512,18 @@ pcl::PointCloud<pcl::PointXYZRGBNormal>::Ptr RTABMAP_EXP extractIndices(
bool negative, bool negative,
bool keepOrganized); bool keepOrganized);
pcl::IndicesPtr extractPlane(
const pcl::PointCloud<pcl::PointXYZ>::Ptr & cloud,
float distanceThreshold,
int maxIterations = 100,
pcl::ModelCoefficients * coefficientsOut = 0);
pcl::IndicesPtr extractPlane(
const pcl::PointCloud<pcl::PointXYZ>::Ptr & cloud,
const pcl::IndicesPtr & indices,
float distanceThreshold,
int maxIterations = 100,
pcl::ModelCoefficients * coefficientsOut = 0);
} // namespace util3d } // namespace util3d
} // namespace rtabmap } // namespace rtabmap

View File

@@ -1,5 +1,5 @@
/* /*
Copyright (c) 2010-2014, Mathieu Labbe - IntRoLab - Universite de Sherbrooke Copyright (c) 2010-2016, Mathieu Labbe - IntRoLab - Universite de Sherbrooke
All rights reserved. All rights reserved.
Redistribution and use in source and binary forms, with or without Redistribution and use in source and binary forms, with or without
@@ -58,7 +58,8 @@ cv::Mat RTABMAP_EXP create2DMapFromOccupancyLocalMaps(
float & xMin, float & xMin,
float & yMin, float & yMin,
float minMapSize = 0.0f, float minMapSize = 0.0f,
bool erode = false); bool erode = false,
float footprintRadius = 0.0f);
cv::Mat RTABMAP_EXP create2DMap(const std::map<int, Transform> & poses, cv::Mat RTABMAP_EXP create2DMap(const std::map<int, Transform> & poses,
const std::map<int, pcl::PointCloud<pcl::PointXYZ>::Ptr > & scans, const std::map<int, pcl::PointCloud<pcl::PointXYZ>::Ptr > & scans,
@@ -76,8 +77,9 @@ void RTABMAP_EXP rayTrace(const cv::Point2i & start,
cv::Mat RTABMAP_EXP convertMap2Image8U(const cv::Mat & map8S); cv::Mat RTABMAP_EXP convertMap2Image8U(const cv::Mat & map8S);
void RTABMAP_EXP projectCloudOnXYPlane( template<typename PointT>
pcl::PointCloud<pcl::PointXYZ>::Ptr & cloud); typename pcl::PointCloud<PointT>::Ptr projectCloudOnXYPlane(
const typename pcl::PointCloud<PointT> & cloud);
// templated methods // templated methods
template<typename PointT> template<typename PointT>
@@ -92,7 +94,8 @@ void segmentObstaclesFromGround(
int minClusterSize, int minClusterSize,
bool segmentFlatObstacles = false, bool segmentFlatObstacles = false,
float maxGroundHeight = 0.0f, float maxGroundHeight = 0.0f,
pcl::IndicesPtr * flatObstacles = 0); pcl::IndicesPtr * flatObstacles = 0,
const Eigen::Vector4f & viewPoint = Eigen::Vector4f(0,0,100,0));
template<typename PointT> template<typename PointT>
void segmentObstaclesFromGround( void segmentObstaclesFromGround(
const typename pcl::PointCloud<PointT>::Ptr & cloud, const typename pcl::PointCloud<PointT>::Ptr & cloud,
@@ -104,7 +107,25 @@ void segmentObstaclesFromGround(
int minClusterSize, int minClusterSize,
bool segmentFlatObstacles = false, bool segmentFlatObstacles = false,
float maxGroundHeight = 0.0f, float maxGroundHeight = 0.0f,
pcl::IndicesPtr * flatObstacles = 0); pcl::IndicesPtr * flatObstacles = 0,
const Eigen::Vector4f & viewPoint = Eigen::Vector4f(0,0,100,0));
template<typename PointT>
void occupancy2DFromGroundObstacles(
const typename pcl::PointCloud<PointT>::Ptr & cloud,
const pcl::IndicesPtr & groundIndices,
const pcl::IndicesPtr & obstaclesIndices,
cv::Mat & ground,
cv::Mat & obstacles,
float cellSize);
template<typename PointT>
void occupancy2DFromGroundObstacles(
const typename pcl::PointCloud<PointT>::Ptr & groundCloud,
const typename pcl::PointCloud<PointT>::Ptr & obstaclesCloud,
cv::Mat & ground,
cv::Mat & obstacles,
float cellSize);
template<typename PointT> template<typename PointT>
void occupancy2DFromCloud3D( void occupancy2DFromCloud3D(

View File

@@ -1,5 +1,5 @@
/* /*
Copyright (c) 2010-2014, Mathieu Labbe - IntRoLab - Universite de Sherbrooke Copyright (c) 2010-2016, Mathieu Labbe - IntRoLab - Universite de Sherbrooke
All rights reserved. All rights reserved.
Redistribution and use in source and binary forms, with or without Redistribution and use in source and binary forms, with or without

View File

@@ -1,5 +1,5 @@
/* /*
Copyright (c) 2010-2014, Mathieu Labbe - IntRoLab - Universite de Sherbrooke Copyright (c) 2010-2016, Mathieu Labbe - IntRoLab - Universite de Sherbrooke
All rights reserved. All rights reserved.
Redistribution and use in source and binary forms, with or without Redistribution and use in source and binary forms, with or without
@@ -92,18 +92,6 @@ Transform RTABMAP_EXP icpPointToPlane(
float epsilon = 0.0f, float epsilon = 0.0f,
bool icp2D = false); bool icp2D = false);
pcl::PointCloud<pcl::PointXYZ>::Ptr RTABMAP_EXP getICPReadyCloud(
const cv::Mat & depth,
float fx,
float fy,
float cx,
float cy,
int decimation,
double maxDepth,
float voxel,
int samples,
const Transform & transform = Transform::getIdentity());
} // namespace util3d } // namespace util3d
} // namespace rtabmap } // namespace rtabmap

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