Compare commits

..
Author SHA1 Message Date
matlabbe 0070de4aaf explicitly set deps to install instead of relying on buildfarm (#1012)
* explicitly set deps to install instead of relying on buildfarm rtabmap (in case buildfarm build is failing)

* use rosdep instead

* missing rosdep update

* updated rosdep command

* removed rosdep init

* fixed qt_gui_cpp not found

* revert last commit, should be able to use qt_gui_cpp in rosdep

* removed deprecated 18.04
2023-04-09 14:40:57 -07:00
matlabbe 11b4becdde bump 0.21.1 2023-04-09 12:00:53 -07:00
matlabbe 8b8a512cbb Added Icp/ReciprocalCorrespondences (new default true) 2023-04-06 20:57:35 -07:00
matlabbe 141f2d3334 DbViewer: added align gps checkbox 2023-04-05 22:19:54 -07:00
matlabbe 6dca8ab0f3 Fixed seg fault on start with >= VTK9.1, MACOSX: fixed bundle with homebrew 2023-03-25 22:41:28 -07:00
matlabbe fc7a6708c5 iOS: updated copyright years 2023-03-25 14:19:34 -07:00
matlabbe 11e5437eba iOS: Addressing #998 #1001 2023-03-25 14:11:42 -07:00
matlabbe c4e94bcdc3 fix comment removed 2023-03-22 22:20:09 -07:00
matlabbe 51a7122dbe fixed cmake 2023-03-22 20:58:12 -07:00
matlabbe d13f594d9c Fixed build with g2o binaries 2023-03-22 20:49:08 -07:00
matlabbe 85cc6fe3c7 fixed build with latest g2o c++17 (#999) 2023-03-22 20:42:33 -07:00
PonyPC 50a0961f4e Update OdometryORBSLAM.cpp (#991)
Fix RGBD with ORB SLAM
2023-03-20 19:35:39 -07:00
matlabbe a406c37750 gtsam: Fixed metis linker errors on windows. Ceres: updated default solver options (working for BA and pose-graph optimizations, fixed #966) 2023-03-19 13:30:52 -07:00
matlabbe 1cb7f3fb87 octomap: fixed regression on ubuntu 16.04 2023-03-18 14:36:30 -07:00
matlabbe ab99719a78 octomap: use cmake target (#995) 2023-03-18 14:19:16 -07:00
matlabbe e66ea7b42b updated qt6 deploy configurations 2023-03-18 00:13:14 -07:00
matlabbe 46edd15121 Fixed bundle with Qt6 2023-03-16 23:07:13 -07:00
matlabbe e7bea0ec03 Windows: Fixed QVTKWidget error with VTK9.2, fixed ambiguous "byte" compilation error 2023-03-16 19:27:54 -07:00
matlabbe e3b7e9378d integrating c++17 fixes from #959 (ref:https://github.com/flann-lib/flann/pull/392), fixed pop_t error (https://github.com/flann-lib/flann/commit/b6e37553de0dd47dc8fc9035ba5aef163981b6a4) 2023-03-16 17:48:40 -07:00
matlabbe 6fe5e6375f Fixed g2o version not correctly used, D400: set default to IR+Depth 2023-03-13 22:10:24 -07:00
matlabbe 92b9cc89e0 fixed missing build dir 2023-03-13 03:20:06 -07:00
matlabbe 53025bf059 Update for windows release: added FindEigen3.cmake so that g2oConfig.cmake can find Eigen3 not using targets from PCL install, hiding console when creating a bundle app in windows, disabled vtk console 2023-03-13 03:10:16 -07:00
matlabbe e51d161407 Export explicity Qt include dirs (compatibility with old cmake way) 2023-03-05 18:45:27 -08:00
matlabbe 3a3a4ed745 ubuntu 16.04: fixed cmake GREATER_EQUAL not defined 2023-03-05 17:46:01 -08:00
matlabbe d6704ca2ed docker latest deps: added nvidia runtime stuff for convenience 2023-03-05 16:38:09 -08:00
matlabbe 8c5c4f63bf Qt6 compatibility (#968)
* Qt6 Compilation success

* Fixed qt5 backward compatibility

* Fixed build for qt<=5.9 (bionic)

* Added docker file for easy testing with latest Qt/VTK/PCL/OpenCV

* Fixed cmake for qt
2023-03-05 16:34:56 -08:00
matlabbe 98635ae33d GUI: fixed missing cache not republished in appearance-only mode 2023-03-04 13:38:27 -08:00
matlabbe 70cbe52fcf DbViewer: exporting map info in yaml file when exporting 2d occupancy grid (#978) 2023-02-25 17:12:51 -08:00
matlabbe e6e6630d54 fixed typo 2023-02-25 14:05:12 -08:00
matlabbe 34fec972dc try workaround #980 2023-02-25 14:01:00 -08:00
matlabbe 67604a0fb0 cmake-ros workflow: increased setup-ros version to 0.5 2023-02-25 13:56:39 -08:00
matlabbe 731d73b798 CMake Config: added "rtabmap::" prefix for all rtabmap's targets, provide RTABMap_TARGETS list (used by ROS2/ament to detect modern cmake packages). 2023-02-22 23:07:30 -08:00
matlabbe 70c3d5d97f DbViewer: added convenient option to rotate the occupancy grid (affect only optimized graph for localization mode). 2023-02-22 17:20:09 -08:00
matlabbe 23b0b37493 ImageView: updated depth color map gradient, added option to set minimum depth. 2023-02-22 12:34:20 -08:00
matlabbe c7f49134eb DBReader: fixed GUI freezing when consecutive stamps in loaded frames are very far apart. 2023-02-18 14:37:43 -08:00
matlabbe 549fc2a592 Config: Removed QtSvg from public dependency, changed find_package 2023-02-12 23:30:53 -08:00
matlabbe 7005a8aa2a fixed android prebuild error 2023-02-12 16:47:55 -08:00
matlabbe 2065688116 Config: added explicit compoments of dependencies 2023-02-12 16:28:42 -08:00
matlabbe 89e3e10d89 Refactoring RTABMapConfig.cmake with targets (#904)
* Config: Using cmake targets

* fixed RTABMAP_DEPRECATED build error

* fixed melodic build

* cleanup

* Fixed qhull exported library error

* Update svg depend private

* removed g2o from public interface

* Fixed Windows with external project

* removed some required dep

* Fixed nsis error (also fixed unspecified components)

* updated workflow rules
2023-02-12 16:18:01 -08:00
matlabbe 437ed09335 DBReader: added ignore priors option (added to gui and reprocess), Statistics: added info about distance/angle of the localization, RegVis: fixed inliers mean distance on multicam setup, About: added MRPT info 2023-02-10 17:29:10 -08:00
matlabbe 59d220c54f k4a: fixed playback fps and imu handling 2023-02-08 21:15:16 -08:00
matlabbe 2acd8f82b5 fixed #969 2023-02-08 19:02:42 -08:00
matlabbe 724e068194 fixed a seg fault 2023-02-08 18:46:02 -08:00
matlabbe e30e6937fa docker: removed broken alicevision build from bionic 2023-02-05 09:08:01 -08:00
matlabbe 9406b15746 docker: fixed error 2023-02-04 21:33:34 -08:00
matlabbe 67ca39514a docker: fixing assimp cmake related error 2023-02-04 21:10:34 -08:00
matlabbe 5fd0448924 docker cleanup 2023-02-04 17:41:07 -08:00
matlabbe 413be8e824 updated docker 2023-02-03 18:06:56 -08:00
matlabbe dcedd8bb6b Added MRPT optional dependency. Updated localization_pose + its covariance to be always published. 2023-02-03 17:25:38 -08:00
matlabbe e4edee33eb Fixed build with cvsba and ceres 2023-01-28 18:49:58 -08:00
matlabbe 128d3b0d0a ZED: Fixed some warnings (#961) 2023-01-28 16:33:24 -08:00
matlabbe ff61266430 docker: fixed focal-foxy build 2023-01-22 17:06:32 -08:00
matlabbe f928cb6787 docker: added focal-foxy 2023-01-22 16:56:31 -08:00
matlabbe 3a9ae201a7 docker/jammy: added multiarh lib folder for arm64 2023-01-22 16:40:16 -08:00
matlabbe 34af17de59 Docker: Added jammy 2023-01-22 16:14:39 -08:00
matlabbe 95e6a9f039 bump 0.20.23 2023-01-21 16:09:41 -08:00
matlabbe b5eef4b86a DBViewer: ignore marker constraints in refine, add marker priors when optimizing the graph 2023-01-21 15:52:01 -08:00
reito 40ab33031b fix bigobj under MSVC, fix yaml-cpp link. (#957) 2023-01-21 15:50:02 -08:00
reito 0e908206d0 OpenCV 4.7 moved aruco back to opencv repo, and makes some breaking changes. (#955) 2023-01-16 16:41:48 -08:00
matlabbe 6b9f7de782 Fixed a -pedantic warning 2023-01-16 14:14:25 -08:00
matlabbe 22fede9335 Reprocess: added --odom option to recompute odometry. 2023-01-15 15:07:24 -08:00
matlabbe 22917cc1c3 VTK9: Fixed vtkGUISupportQt -> VTK::GUISupportQt 2023-01-14 20:12:33 -08:00
matlabbe 98bf3fb184 workflows: removed galactic build (EOF) 2023-01-08 16:59:24 -08:00
matlabbe 8d301afe6c reprocess: added --default option 2023-01-08 16:29:44 -08:00
matlabbe e3ceb8a572 VINS-Fusion: Fixed error wrongly logged when only imu is processed by vins. 2023-01-08 15:22:46 -08:00
matlabbe f12cc83fc2 RegVis: using toSignature camera model for guess reprojection on optical flow mode (#947) 2022-12-20 20:51:56 -08:00
matlabbe 4a6a765cd1 Fixed #944 2022-12-14 19:42:56 -08:00
matlabbe a4761ad397 Fixed #940 2022-12-11 01:12:21 -08:00
matlabbe aa380de2a7 Update install_deps.sh
Removed vtk default iOS simulator build
2022-12-07 17:59:11 -08:00
matlabbe 467dc738c7 Fixed deprecated warning not set to right function 2022-12-05 20:32:53 -08:00
matlabbe 64cb7fb6fe export: when --images and --cam_projection are used, we export depth image from lidar projection to RGB frames 2022-12-04 17:23:33 -08:00
matlabbe 8a8c360f89 fixed compilation warning 2022-11-27 16:20:56 -08:00
matlabbe 83693ed1b9 detectMoreLoopClosures: fixed guess not set for lidar-only registration (https://github.com/introlab/rtabmap_ros/issues/727) 2022-11-26 20:24:43 -08:00
matlabbe 860c14e0ec rtabmap: fixed export poses in format 10 and 11 (#883) 2022-11-26 12:42:04 -08:00
matlabbe 85bc1ee27f GTSAM: return empty optimized poses in case of exception or error. g2o: don't assert on marginal not computed, log error and reutn empty optimized poses. 2022-11-22 12:26:02 -08:00
matlabbe 05676d1577 ios: Moved install_deps.sh in upper directory to easy cleanup Libraries. Fixed uNumber2Str(double) link error. 2022-11-19 12:41:01 -08:00
matlabbe 6d713c2ccb uNumberToStr(double): added "fixed" param (default false) to fix ros param double/int conversion issue. 2022-11-11 16:20:59 -08:00
matlabbe 16e3314e64 💄 2022-11-11 14:45:33 -08:00
matlabbe d59a306ae3 Export: fixed depth image wrongly set for stereo data 2022-11-10 17:18:57 -08:00
matlabbe bdfab4e0be reprocess: added "-a" option (append mode) 2022-11-02 15:06:13 -07:00
matlabbe c9d50ef445 Export GPS poses: set 8 decimals (1 mm accuracy) https://github.com/introlab/rtabmap_ros/issues/833 2022-11-02 11:35:54 -07:00
matlabbe 2889cf8048 GUI: fixed latest data requested on localization mode 2022-10-31 13:21:13 -07:00
matlabbe def876983d docker/android: fixed docker not detecting compilation failure. ios: added exit flag for install_deps.sh script 2022-10-30 15:07:55 -07:00
matlabbe 69214b927a fixed android build 2022-10-30 14:47:34 -07:00
matlabbe 67b2cbe5ca docker: set dummy build-args for build not required them 2022-10-30 14:39:33 -07:00
matlabbe 86f66cc8b8 Added missing signature info in republished data 2022-10-30 13:59:08 -07:00
matlabbe d70924a3a4 bump package version 0.20.22 2022-10-28 12:30:01 -07:00
matlabbe 1297714271 Bump version 0.20.22. Refactored RtabmapThread commands handling. MainWindow/RtabmapThread/Statistics/UVariant: added new option to republish missing data on GUI side. MainWindow: fixed 1 sec lag when waypoints are used. Parameters: added Rtabmap/MaxRepublished (moved from rtabmap_ros). OccupancyGrid: fixed ground cells ignored if there are empty cells, also don't add pose in addedNodes if corresponding node was not in cache. 2022-10-28 12:25:48 -07:00
matlabbe 8e30c1c812 GraphView: added user link on inter/intra loop closure color scheme option 2022-10-24 17:45:16 -07:00
matlabbe df888962f4 depthai: fixed app freezing if oakd device (oak-d lite) doesn't have imu and imu is requested. 2022-10-24 11:13:27 -07:00
matlabbe a8cdf1f940 reprocess: disable Mem/UseOdomFeatures by default when there are more than 1 input database 2022-10-24 10:34:37 -07:00
matlabbe 769ace86ce Added oak-d lite menu option (depthai: imu is now optionnal) 2022-10-23 18:15:23 -07:00
matlabbe 97a150b180 DbViewer: added option to regenerate optimized 2d map from OctoMap (https://github.com/introlab/rtabmap_ros/issues/213) 2022-10-23 12:16:35 -07:00
matlabbe 6e8f43916c floam: republish input scan with features 2022-10-16 21:31:43 -07:00
matlabbe 5b0047efad docker: fixed AliceVision build (bionic/focal) 2022-10-15 14:06:20 -07:00
matlabbe fdb78d33b0 DBViewer: added optimzed and prior poses in node details. Reprocess: add start_s, stop_s and pub_loops options. 2022-10-12 13:05:01 -07:00
matlabbe 2cbd43dfb6 Update cmake-ros.yml
Added ros2 distros
2022-10-09 12:47:03 -07:00
matlabbe 1f06386f37 Update README.md 2022-10-09 12:22:09 -07:00
matlabbe 1e9b090624 Gui: Added re-localization colors on odom cache graph. Added frame labels (map, odom). 2022-10-04 16:27:33 -07:00
matlabbe 7e3e5ec50b DBViewer: fixed matching lines when two images don't have the same number of cameras. Fixed nodes with w=-9 can be used to add constraint (in case localization data is saved in database). Add constraint: compute transform in order of the sliders. 2022-10-04 14:23:12 -07:00
matlabbe 8d23f19f6c bump ros package version 2022-10-01 18:30:51 -07:00
matlabbe 9afbcf2d06 detectMoreLoopClosures tool: regenerate global occupancy grid for convenience if there was one before 2022-09-30 15:48:09 -07:00
matlabbe 30bf5895ca Fixed #909 2022-09-30 14:17:23 -07:00
matlabbe e0a2adcb45 Updated latest jfr2018 docker 2022-09-27 16:37:25 -07:00
matlabbe 87faea7a85 Fixed ceres linker issue with floam dependency (if WITH_CERES is OFF) 2022-09-27 23:35:13 +00:00
matlabbe 74c6e9cfec Fixed compilation error about stereoCameraModel() not found (#905) with OpenVINS odometry 2022-09-27 13:48:57 -07:00
matlabbe 675dad5f76 Fixed compilation error about stereoCameraModel() not found (#905) with odometry approaches: Fovis, MSCKF, Okvis, VINS, Viso2. 2022-09-27 18:56:05 +00:00
matlabbe 55546132a0 Fixed build on 16.04 2022-09-27 17:22:52 +00:00
matlabbeandmathieu86 fa31affea0 Pnp multicam refactoring (#902)
* gui: fixed wrongly showing landmark rejected when it was not (because a loop closure was rejected at the same time)

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

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

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

* loc/small movement: cleanup bidirectional links

* Cov/PnP: fixed objPt transform to estimate depth

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

* Fixed marker detection on camera index> 0

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

* Fixed build without opengv

* Cmake: moved OpenGV dependency status under solvers group

* Added multi-stereocamera models support

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

* Fixed multicam 3d points generated from stereo correspondences

* db: Fixed multi stereo models not loaded correctly

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

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

* depthai: added imu firmware update option for convenience

* Fixed various refactor errors

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

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

* fixed compilation errors with latest opencv

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

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

* Marker: added priors variance parameters

* g2o: refactored backward compatibility includes

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

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

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

* workflow-cmake: fixed path to bin directory
2021-11-14 19:29:37 -05:00
matlabbe 6c07a670ee Added OdometryOpen3D 2021-11-13 19:45:57 -05:00
matlabbe 4ba805b5b3 Report: fixed landmarks not used during optimization. Reprocess: added --nolandmark option to ignore landmarks in input database. 2021-11-12 12:47:54 -05:00
matlabbe b002e85e0f Update ProgressDialog.h
Typo param name should be in seconds, not milliseconds.
2021-11-09 17:36:34 -05:00
matlabbe ec2aa5c952 OpenNI2: depth shift can be negative. MainWindow: postProcessing() refactoring (split with and without dialog). 2021-11-09 10:16:12 -05:00
matlabbe 06150c697f Fixed #750 2021-11-08 14:20:21 -05:00
matlabbe 38bcb0060c CMake: set default to OFF for some optional dependencies that require specific versions or patches before integrating with rtabmap, otherwise there could be seg faults on runtime even if compilation worked. 2021-11-08 13:47:27 -05:00
matlabbe ddd5eb5a41 CameraRealSense2: Odom extrinsics against another sensor can be calibrated with having to calibrate stereo first. DBViewer: fixed local grid wrongly using global grid parameters. 2021-11-05 18:05:50 -04:00
matlabbe 20bc281db7 DbViewer: don't show landmark links for ignored ndoes (w=-9), auto-zoom grid map if there are a lot of unknowns. Updated Docker nvidia files to include default Documents/RTAB-Map directory. 2021-11-04 13:00:08 -04:00
matlabbe 7c5acd8970 Parameters: Changed Grid/FromDepth to Grid/Sensor to add a new choice to use both scan and depth for local grids. Increased version to 0.20.15. 2021-10-29 20:05:12 -04:00
matlabbe 1886f99cbf Merge branch 'RobotnikAutomation-master' 2021-10-29 13:58:14 -04:00
matlabbe 2ad334df90 Added filter_floor and adjusted default values. 2021-10-29 13:58:00 -04:00
matlabbe 0ab5a8f43e Merge branch 'master' of https://github.com/RobotnikAutomation/rtabmap into RobotnikAutomation-master 2021-10-29 13:57:16 -04:00
matlabbe 8682026396 Rtabmap: when optimizing graph, removed guess for rootid to avoid global rotation drift over time. CameraStereoImages: set BayerMode also to right image. GraphView: fixed 0 width for line inside NodeItem. Reprocess: added -loc_null and -gt options. 2021-10-23 11:17:42 -04:00
Ines 6cb741667d Add ceiling filter to rtabmap-export 2021-10-22 12:36:53 +02:00
matlabbe 56c5622d20 docker: added "make -j12" for rtabmap build 2021-10-16 18:14:24 -04:00
matlabbe e245782c6c worflows: added back arm64 2021-10-15 14:58:56 -04:00
matlabbe 9895e4c162 workflow: test images without arm64 2021-10-15 09:29:34 -04:00
matlabbe f67087075a Updated docker images (removed amd64 script) 2021-10-14 21:49:50 -04:00
matlabbe d0242b14cf DetectMoreLoopClosures CLI: show overridden parameters 2021-10-11 13:52:55 -04:00
matlabbe d16e24a1a3 Fixed compiler warning 2021-10-07 10:19:32 -04:00
matlabbe ab5fd5018b DbViewer: added update all landmark covariances menu action, also enabled edit constraint on landmark links. Covariance can be set to 9999. 2021-10-06 11:34:40 -04:00
matlabbe 44810a14e0 Show if built with PDAL on --version option 2021-10-01 11:49:45 -04:00
matlabbe 697fe5ebb3 Workflows: updated docker multi-arch (removed armv7) 2021-09-30 18:00:17 -04:00
matlabbe 54c0ee4244 Workflows: added multi-arch docker images 2021-09-30 15:37:05 -04:00
matlabbe d284cd11cf Updated package.xml version to 0.20.14 2021-09-30 10:14:24 -04:00
matlabbe 467ea42981 OdometryFLOAM: fixed published local scan map local transform 2021-09-30 10:05:56 -04:00
matlabbe 77d947d4fb Fixed FLOAM not working when local transform is not Identity. DBViewer: warn user when scan from dpeth is checked and there are no depth images in db. 2021-09-30 09:53:50 -04:00
matlabbe 533d78d570 Fixed OdometryOpenVINS build errors with latest OpenVINS code. 2021-09-28 17:12:08 -04:00
matlabbe aee034c5ed Update CMakeLists.txt
Setting WITH_FLOAM to OFF by default because floam binaries (this [version](https://github.com/flynneva/floam)) in ros is not compatible.
2021-09-27 20:20:11 -04:00
matlabbe 0092e15cd7 Update docker.yml 2021-09-27 20:04:12 -04:00
matlabbe 23d9e0e4bb Docker: updated bionic/focal's geogram patch 2021-09-27 19:48:18 -04:00
matlabbe 8c56b5b1ce CMake: added WITH_OPENMP option (to be able to disable it). CameraOpenNI2: Added depth decimation parameter. CLAMS: can apply distortion model to smaller images. 2021-09-24 17:31:16 -04:00
matlabbe bccc5b13af FLOAM: added some debug logs 2021-09-24 11:32:25 -04:00
matlabbe 5f65618d40 Added OdomLOAM/Resolution parameter 2021-09-22 10:48:59 -04:00
matlabbe cff0d15460 Fixed "wrong scan number" error when OdomLOAM/Sensor is 0 (VLP16) 2021-09-22 10:06:34 -04:00
matlabbe b6671f4d8c workflow/docker: added CACHE_DATE to android builds to avoid caching rtabmap build 2021-09-20 16:02:37 -04:00
matlabbe 9db66600b3 workflow: added android23 docker image 2021-09-20 15:46:14 -04:00
matlabbe 67cd4b69c1 workflow: updated docker tags / cache var 2021-09-20 13:34:30 -04:00
matlabbe cffb7981b6 docker: fixed bionic build with latest alicevision (cmake>=3.11 required) 2021-09-20 12:32:51 -04:00
matlabbe 71ffd922ed workflow: fixed typo 2021-09-20 11:37:58 -04:00
matlabbe 870467393b workflow: add docker buildcache 2021-09-20 11:33:19 -04:00
matlabbe 79f203a2c4 docker workflow: fixed build matrix 2021-09-20 11:16:12 -04:00
matlabbe baa5b638ae Added "docker" workflow 2021-09-20 11:11:21 -04:00
matlabbe 8f12463f71 Docker: upgraded alicevision version 2.4.0 in bionic/focal images 2021-09-19 20:42:56 -04:00
matlabbe 14b56813d3 Updated for AliceVision >=2.4.0 compatibility. Export: added --multiband_contrib option. 2021-09-19 20:20:45 -04:00
matlabbe 44b057b0d7 DbViewer: fixed icp from depth option not used when refining or adding loop closures automaticaly 2021-09-13 15:59:19 -04:00
matlabbe a901f20d06 0.20.14: added globalBundleAdjustment CLI, added Rtabmap/Memory::cleanupLocalGrids function, init with optimizedPoses from db even in mapping mode, reprocess: added -db option to save optimized 2d grid in database. 2021-09-11 11:35:43 -04:00
matlabbe 3ba02d2ef6 Added OdometryFLOAM (Odom/Strategy=11) 2021-09-09 17:38:54 -04:00
matlabbe 263e0170f1 export: refactored ba (to support stereo data) 2021-09-09 14:22:02 -04:00
matlabbe e017a0fcf4 DbViewer: fixed initial rootid with older databases, fixed RGBD/OptimizeFromGraphEnd not correctly used. 2021-09-08 18:13:20 -04:00
matlabbe 103db3181b Update README.md 2021-09-08 17:13:13 -04:00
matlabbe bc253df24a Update README.md 2021-09-08 17:11:34 -04:00
matlabbe 544ea9dff2 Update cmake.yml 2021-09-08 13:31:00 -04:00
matlabbe 09c2c4bbcb Removed travis config, now use Github actions (see .github/workflows/cmake.yml) fixed #768 2021-09-08 12:09:59 -04:00
matlabbe c209cf1c9b Update cmake.yml
Added info after build
2021-09-08 12:06:14 -04:00
matlabbe 202d59b408 Update cmake.yml
Added ros setup.bash before cmake
2021-09-08 11:59:04 -04:00
matlabbe 9671daf9c3 Update cmake.yml 2021-09-08 11:53:13 -04:00
matlabbe b5518ff618 Update cmake.yml 2021-09-08 11:46:29 -04:00
matlabbe 2111b6497b Update cmake.yml
use setup-ros action
2021-09-08 11:37:03 -04:00
matlabbe b51b2525a5 Added Github actions for melodic/focal 2021-09-08 11:24:11 -04:00
matlabbe 45d51808e3 💄 2021-09-08 09:38:16 -04:00
matlabbe bc39b19517 projectCloudToCamerasImpl: fixed bug using wrong camera models 2021-09-08 09:34:21 -04:00
matlabbe 7baedf4c72 texturing: remove assert when poses and models are not the same size (just ignore poses without models, intermediate nodes issue) 2021-09-07 16:26:56 -04:00
matlabbe 20361400e1 export: output intensity channel with RGB when --cam_projection and --scan options are set (PDAL required) 2021-09-07 15:57:23 -04:00
matlabbe c43118cde8 Fixed F2F-Optical flow not creating keyframes bug 2021-09-03 15:33:22 -04:00
matlabbe 371a3ef851 fixed CleanupLocalGrids install target 2021-09-01 10:23:45 -04:00
matlabbe daefc5ff54 Added rtabmap-cleanupLocalGrids CLI 2021-08-28 22:19:59 -04:00
matlabbe b932da6dcf DbViewer: Adjusted GraphView's root id based on latest valid node on initialization 2021-08-28 20:23:44 -04:00
matlabbe f88ce1618b OdometryORBSLAM3: fixed re-initilisation of camera parameters when restarting camera with different config. 2021-08-26 15:34:48 -04:00
matlabbe c5e4d67f80 export: don't assert if gain is zero (means disabled) 2021-08-16 20:27:31 -04:00
matlabbe ed68fe777b Added more options for multiband texturing 2021-08-16 13:14:02 -04:00
matlabbe 6fb553a5e7 Update README.md 2021-08-13 14:46:56 -04:00
matlabbe db00e04cc1 rtabmap-info: updated to show parameters not in the database. 2021-08-12 10:55:08 -04:00
matlabbe eeecb21793 export tool: added --camera_projection_keep_all option 2021-08-03 13:46:39 -04:00
matlabbe a5685c3e31 Fixed build without DepthAI dep 2021-07-28 17:05:16 -04:00
matlabbe 138d4aa1be If RGBD/LoopClosureReextractFeatures=true, don't save raw features (3d point, descriptor) to Feature table. 2021-07-28 14:32:32 -04:00
matlabbe 79d2b3fade Merge branch 'master' of https://github.com/introlab/rtabmap 2021-07-28 14:19:49 -04:00
matlabbe 32bf0f9d61 Fixed CameraDepthAI with latest depthai version (using now camera eeprom calibration and added imu support) 2021-07-28 14:19:30 -04:00
matlabbe 22a771e29c trigger travis.com 2021-07-20 14:09:40 -04:00
matlabbe 17d8a92614 Update README.md 2021-07-20 12:58:42 -04:00
matlabbe a91cd0c659 Update README.md 2021-07-20 12:58:16 -04:00
matlabbe ae92ec40d7 Fixed build with LOAM dependency 2021-07-14 13:22:47 -04:00
matlabbe 7338cb8a85 Localization: fixed initial graph optimization root id (based on RGBD/OptimizeFromGraphEnd) when optimized graph is not saved in db. 2021-07-09 14:57:15 -04:00
matlabbe 456560b9e4 DBViewer/Extract Images: export calibration for each image, also now export multi-camera calibrations. 2021-07-07 12:21:57 -04:00
matlabbe f9257beeb8 export: updated default poses format (11) 2021-07-05 12:58:24 -04:00
matlabbe 485bf806bd export tool: use pcl's PLY writer instead of pdal if camera ids are not exported (ply compatibility issue when reading back using pcl) 2021-07-05 10:04:51 -04:00
matlabbe 68ae3b76af export: updated to export calibration for every files (to support auto-focus cameras). Added output_dir option. 2021-07-05 09:46:12 -04:00
matlabbe 05d45872f3 DBReader: publish landmarks by default (also added option to ignore them) 2021-06-29 16:03:21 -04:00
matlabbe 3da4bb9faa For Icp/DebugExportFormat and RGBD/ProximityGlobalScanMap, use Rtabmap/WorkingDirectory as output directory for debugging files. 2021-06-27 20:37:42 -04:00
matlabbe a921d615c5 0.20.13: templated laserScanFromPointCloud() version with PCLPointCloud2 to be also used with sensor_msgs/PointCloud2 class (for rtabmap_ros). 2021-06-27 20:07:00 -04:00
matlabbe 2b9ae3a2ad Added Icp/DebugExportFormat parameter 2021-06-26 16:06:25 -04:00
matlabbe 1a64e05e2f fixed code merged 2021-06-26 13:47:49 -04:00
matlabbe 350f995ee9 merged master to scan_map branch 2021-06-25 16:38:03 -04:00
matlabbe eabf3e3d57 Decimation parameters for feature detection cannot be negative anymore (always done based to RGB image and depth image is decimated only if it is bigger than decimated rgb image). MainWindow: fixed light blue screen-only on full rehearsal merge. 2021-06-25 12:54:52 -04:00
matlabbe be24203840 iOS: added toast info on rejected loop closures 2021-06-24 22:39:25 -04:00
matlabbe 48ebf969bd OdometryInfo: fixed IcpRMS not copied in copyWithoutData() 2021-06-24 22:38:19 -04:00
matlabbe 656618ccb7 Merge branch 'master' of https://github.com/introlab/rtabmap into scan_map 2021-06-24 19:53:23 -04:00
matlabbe f5ab422c42 Odom: when odom is auto reset, reprocess the latest image and return its pose 2021-06-24 13:41:38 -04:00
matlabbe 5a676e9032 Fixed negative Odom/ImageDecimation not handled 2021-06-24 12:44:18 -04:00
matlabbe 11e9837b82 Added RGBD/ProximityGlobalScanMap for proximity detection using the whole scan map in localization mode. Added Icp RMS statistics (CCCorelib). Updated how localization is corrected with gravity when available (simply use roll and pitch of current gravity constraint). 2021-06-23 17:13:07 -04:00
matlabbe dddf6378ae MainWindow: fixed currentVisiblePosesMap 2021-06-22 08:16:39 -04:00
matlabbe 5167927d01 report: added --ignore_inter_nodes option. CloudViewer: set max absolute scan intensity to 100 (was 0=auto). reprocess/replay db: ignore intermediate nodes if Rtabmap/CreateIntermediateNodes is false. 2021-06-21 17:23:53 -04:00
matlabbe f475f2d21c 0.20.12: iOS/android sync 2021-06-21 10:07:30 -04:00
matlabbe 9fccb8703a Merge branch 'master' of https://github.com/introlab/rtabmap into ios 2021-06-21 09:41:11 -04:00
matlabbe 62b5f13dd8 MainWindow: added currentVisiblePosesMap() 2021-06-20 23:05:24 -04:00
matlabbe b8c22e1c99 Fixed pcl::voxelGrid filtering crash on Windows (latest PCL, eigen allocation issue) 2021-06-18 16:02:17 -04:00
matlabbe d75cc04ad2 CloudViewer: fixed opengl not refreshed on update (VTK9). Fixed File Explorer hanging (Qt 5.12). Fixed backup database not deleted after a recovery. 2021-06-18 12:43:08 -04:00
Charles Maillette 8d2dbe32c4 Added libpdal to rtabmap docker build for focal (#735) 2021-06-17 15:36:28 -04:00
matlabbe a9d4fc9291 Refactored Tango and ARCore texture management. Tango: added support with First-person AR mode. ARCoreJava: Added localization filtering speed option (avoid ARCore jumps), also manage when ARCore is lost (new session is created, relocalization needed to continue mapping). 2021-06-15 20:45:45 -04:00
matlabbe 696216b35b Fixed occlusion image origin offset (iOS and android). Android: disabled maximum odom image rate for faster feedback in First-Person. Min/Max range parameters also filter scans. Fixed background renderer not showing image (ARCore Java driver). 2021-06-13 22:07:47 -04:00
matlabbe 6342658ec5 iOS: fixed origin when we do New Scan while we were already mapping, improved FPV feedback in point cloud mode, showing camera overlay in visualization mode (pinch out to disable). Localization mode: Updated how marker detection transform are modified by gravity constraints. 2021-06-12 12:42:56 -04:00
matlabbe 3f633081cb iOS: improved feedback in first-person mapping mode (red background), fixed not matching camera overlay with 3D model, updated how memory usage is computed. 2021-06-11 21:41:59 -04:00
matlabbe a6f3a81999 fixed ios build 2021-06-11 10:20:07 -04:00
matlabbe 3e3d4142fc RGBD/OptimizeMaxError default to 1 for mobile apps. iOS: increased Kp/MaxFeatures to 400 (was 200). 2021-06-11 09:29:37 -04:00
matlabbe 0a37d01d1d ios/android: Updated default MaxOptimizeError to 1.5x 2021-06-10 11:27:53 -04:00
matlabbe ba38d9f321 Added depth/rgb registration option 2021-06-10 11:07:25 -04:00
matlabbe d7b5fa5d17 fixed android build 2021-06-09 17:45:01 -04:00
matlabbe 766301b175 fixed desktop build 2021-06-09 11:25:01 -04:00
matlabbe 289d4afd76 ios first release 2021-06-08 00:06:49 -04:00
matlabbe 630cb6a59f Odometry: when "Rtabmap/ImagesAlreadyRectified" is false and odometry strategy doesn't support raw images, added rectification for RGB-D data (only rgb rectified though) for convenience. 2021-06-01 14:33:17 -04:00
matlabbe 12c46286f6 CameraRealSense2: added support for device id like D435, t265, L515, d435i, d415 for convenience (if we have multiple D435, we still need to use on of the serials shown in log info when starting the driver) 2021-06-01 11:40:46 -04:00
matlabbe c9dbe6205d Docker: added nvidia drvier embedding examples for convenience 2021-05-30 14:21:17 -04:00
f94f9cbb9b improve flood fill and move it to update function (#727)
* add flood fill filter

* change to use unordoned_multiset

* remove recursivity in flood fill and move the flood fill into the update

* Refactoring of OctoMap constructors (keeping only one). Simplified floodfill parameters to only one and added it to UI.

* Fixed ray tracing not done in local 3D maps (OctoMap)

Co-authored-by: MarcLeclercGit <marcantoine.leclerc96@gmail.com>
Co-authored-by: matlabbe <matlabbe@gmail.com>
2021-05-30 10:12:07 -04:00
matlabbe b7c2f6801b unknownSpaceFilled: refactored approach to fix the case of 360 scan with first ray y>=0 (turtlebot3 sim). 2021-05-27 18:19:34 -04:00
matlabbe 8b1b874bf3 Statistics: added LoopOptimization_max_ang_error stats 2021-05-27 13:00:29 -04:00
matlabbe 127a41a53e MainWindow::createCamera() fixed parameters not passed by reference 2021-05-26 21:13:14 -04:00
matlabbe c1492533c3 OctoMap: fixed empty cells not all added to global occupancy grid 2021-05-26 16:27:49 -04:00
matlabbe ada3e75005 Camera class: localTransform parameter should not have optical rotation anymore (it is added afterwards in the constructor). OdomSensor: the extrinsics should not contain optical rotation anymore. These 2 changes make it more convenient to set transfomation parameters in the UI. MainWindow::createCamera() now has odomSensor argument for convenience (for inherited classes to set both camera and odom sensor in the same function). 2021-05-26 13:40:46 -04:00
matlabbe 21dbeed4b7 Odom sensor option (#726)
* Added Odom Sensor option

* Odom Sensor: Added pose time offset parameter

* Gui: fixed odom cloud not shown when rgb/depth doesn't have same size. Odom sensor: fixed rawImages set on non-stereo camera (because stereoRectify wrongly set to all cameras)

* Calibration: fixed rgb and depth suffixes not correctly set. OpenNI2: horizontal and vertical shifts can be also set for default calib.

* Fixed a warning

* OdomSensor: added option to use odom sensor output as ground truth (for comparison between odom sensor and rtabmap odom). Added scale factor option.

* FindG2O.cmake: updated path suffixes to find EXTERNAL csparse

* Pose3GravityFactor: fixed dllimport error on windows

* UI: Statistics panel not updated if not visible and keep stats in cache is unchecked. Added description to some timing debug logs in processStatistics().

* Removed vtkOutputWindow on Windows

* Odom Sensor: added zed sdk support

* bump version 0.20.11
2021-05-23 17:21:12 -04:00
matlabbe fe896260c5 commonFiltering(): warn when normals could not be computed (returned all NaNs) 2021-05-16 11:58:17 -04:00
matlabbe 56bc15d7cd MainWindow: fixed bg color not shown on loop closures when only scans are used. 2021-05-16 11:15:05 -04:00
matlabbe e9d7fcd7ae Vtk9 support (#722)
* Fixed build with VTK9

* Fixed VTK9 build with OctoMap dependency (vtkRenderingVolumeOpenGL2 missing)
2021-05-15 19:43:47 -04:00
matlabbe 8c336e1e39 Voxel filter: added support for very large clouds. Gui/Export: added footprint filtering option. Moved all filtering options under Cloud Filtering group. 2021-05-14 21:02:09 -04:00
matlabbe 4390cb6428 calibration tool: added RealSense2 T265 support 2021-05-12 18:31:41 -04:00
matlabbe 20c2e8b5be Docker: updated libpointmatcher version in bionic/focal images (https://github.com/introlab/rtabmap/issues/720) 2021-05-12 14:01:26 -04:00
matlabbe ad8b2301d8 Docker/focal: fixed alicevision patch corrupted (no newline) 2021-05-12 11:27:26 -04:00
matlabbe d75f9524f3 Export: added --texture_depth_error option 2021-05-12 10:56:16 -04:00
matlabbe aedc70218b Docker: added AliceVision dependency to focal image 2021-05-12 10:38:37 -04:00
matlabbe a11492943a Export CLI: added print info for coloring mesh step 2021-05-10 15:19:48 -04:00
matlabbe 854a52c6a5 Export CLI: added noise_radius and noise_k options to filter noise 2021-05-10 14:45:35 -04:00
chameau5050andMarcLeclercGit b4f11e18f3 add flood fill filter (#714)
* add flood fill filter

* change to use unordoned_multiset

Co-authored-by: MarcLeclercGit <marcantoine.leclerc96@gmail.com>
2021-05-07 17:05:01 -04:00
matlabbe 6449302318 appveyor: added opencv 4.5.0 binaries with opencv_contrib 2021-05-02 21:41:48 -04:00
matlabbe 3623ede989 Update .appveyor.yml 2021-05-02 20:37:45 -04:00
matlabbe 0e051a16a0 Update .appveyor.yml 2021-05-02 20:00:16 -04:00
matlabbe c88e3d0a8b Update .appveyor.yml 2021-05-02 19:55:57 -04:00
matlabbe ff956a725e Fixed "localization won't be corrected with gravity" warning in localization mode and imu data are not used (while Optimizer/GravitySigma>0) 2021-05-02 19:42:59 -04:00
matlabbe 40ab98a814 docker-focal: cleanup downloaded k4a binaries 2021-05-02 13:30:57 -04:00
matlabbe f02efb5836 docker-focal: added libfreenect2, k4a, realsense2, zed open capture support (#673) 2021-05-02 13:17:53 -04:00
matlabbe 0764999f22 Fixed focal docker image with gtsam (#673) 2021-05-02 11:59:36 -04:00
matlabbe 7515556444 Update LICENSE 2021-04-23 20:42:39 -04:00
matlabbe 3b7c6cd1f4 DBViewer: added camera projection on scan option (GUI params). Fixed some deprecated warnings. 2021-04-19 18:14:20 -04:00
matlabbe 93bfad626e Update .travis.yml
Removed deprecated trusty build from travis (https://travis-ci.org/github/introlab/rtabmap/jobs/766950721)
2021-04-14 13:12:31 -04:00
matlabbe 2fcef88016 Export: added --poses_format option (default 10=RGBD-SLAM format). Added new pose format 11=RGBD-SLAM + ID. 2021-04-13 15:49:04 -04:00
matlabbe f4207979ad Export: fixed calibration not exported if camera name is not set. For multi-camera, added index suffix to yaml. 2021-04-09 16:20:08 -04:00
matlabbe b92f55be43 Export tool: added multi-camera support when exporting camera poses 2021-04-08 10:23:38 -04:00
matlabbe a8f0abf892 MainWindow::processOdometry() rectify images if Rtabmap/ImagesAlreadyRectified is false. 2021-04-02 19:06:03 -04:00
matlabbe 54267b1b33 Preferences: fixed backward compatibility error "Conversion failed from true for parameter Icp/Strategy" when loading old database with Icp/PM 2021-03-31 12:02:56 -04:00
matlabbe 4c1e72d82e Added OpenVINS minimal support (tested with EuRoC dataset) 2021-03-28 23:51:02 -04:00
matlabbe a58ec494d1 icpCC: when force3DoF is true, set z to 0 in data conversion 2021-03-28 09:28:55 -04:00
matlabbe 69735b6271 Added removeNaNFromPointCloud for PCLPointCloud2 type 2021-03-28 00:15:47 -04:00
matlabbe d002711f21 reprocess tool: Updated usage description to upgrade db version 2021-03-27 16:21:52 -04:00
matlabbe 06e85e140c Refactored RegistrationIcp: libpointmatcher yaml config usage / integrated CCCoreLib (#704)
* Refactored RegistrationIcp so that libpointmatcher yaml can work with icp odometry (we can then avoid refiltering data with local map of F2M). All data filtering (including libpointmatcher DataFilters) are done at the beginning of the function.

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

* Fixed compilation error without libpointmatcher

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

* Fixed build without CCCoreLib

* Cleanup RegistrationIcp from third party functions.

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

Note: IMU not supported yet with ORB_SLAM3.

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

* fixed regression build error with ORB_SLAM2

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

* Fixed build without DepthAI dependency

* Added minimum version 2 for depthai

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

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

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

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

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

* Fixed python freezing with multi-threading
2021-01-17 01:56:27 -05:00
matlabbe 0bc483b6d3 Added pdal optional dependency (export to LAS, E57, ...) 2021-01-14 15:49:18 -05:00
matlabbe eae5f2b428 fixed #674 2021-01-11 11:38:31 -05:00
matlabbe 94cf1dfd32 Fixed zero-ed 3D words when receiving odometry's 2D keypoints > Kp/MaxFeatures and empty 3D points 2021-01-09 20:52:34 -05:00
matlabbe 1a967127d9 Bump 0.20.8 version. Parameters: updated default of Vis/CorGuessWinSize=40 (was 20), GFTT/MinDistance=7 (was 3), Optimizer/GravitySigma=0.3 if built with g2o or gtsam. Those parameters help for smooth tracking on latest sensors with higher resolution and use IMU by default if available. Updated docker jfr2018 to use original parameters. CameraStereoZed: wait for imu to be available before sending frames (Zed-m and Zed2). 2021-01-08 13:04:24 -05:00
matlabbe 792c967d46 MainWindow: added driver options to differentiate between cameras having IMU or not (D400 vs D435i, ZED vs Zedm and Zed2). Enabled imu filtering by default for Freenect driver (Kinect XBOX360). 2021-01-08 01:10:23 -05:00
matlabbe a67dbc26f2 L515 refactoring (realsense v2.41.0, firmware 1.5.3): added IR-only mode support, fixed support with latest firmware, T265+L515 working, related to #574 #614 #629. MainWindow: Selecting RealSense2, ZED sdk, K4A, Mynteye drivers automatically enable gravity optimization (with IMU filtering). 2021-01-08 00:01:08 -05:00
matlabbe f1993d9cd7 android: fixed z-fighting on some android devices 2021-01-02 18:14:55 -05:00
matlabbe da99d7e4a0 disabled osx travis build (too long to do) 2020-12-20 00:07:34 -05:00
matlabbe e896ffb5c0 Update .travis.yml 2020-12-19 23:16:28 -05:00
matlabbe 04cbf56cc0 Update .travis.yml 2020-12-19 22:37:13 -05:00
matlabbe c5051bf82a Update .travis.yml 2020-12-19 21:38:13 -05:00
matlabbe 7a9f01b9a3 Update .travis.yml 2020-12-19 12:55:12 -05:00
matlabbe 70094edb75 Update .travis.yml 2020-12-19 12:38:36 -05:00
matlabbe eb2af19a89 Update .travis.yml 2020-12-19 12:28:02 -05:00
matlabbe af227bad51 Update .travis.yml 2020-12-19 12:21:25 -05:00
matlabbe ee63ce338a Update .travis.yml 2020-12-19 12:11:19 -05:00
matlabbe 1b3a6abb82 Update .travis.yml 2020-12-19 11:48:06 -05:00
matlabbe 4a8a20c7d1 Update .travis.yml 2020-12-19 11:24:19 -05:00
matlabbe a125797e50 Update .travis.yml
Added osx
2020-12-19 11:18:20 -05:00
matlabbe a6f0877045 Parameters: added Rtabmap/ImagesAlreadyRectified to odometry parameters (to be shown with --params) 2020-12-18 17:57:43 -05:00
matlabbe b5cae38eb9 Fixed -lBoost:timer not defined when building with latest GTSAM binaries 2020-12-18 17:01:11 -05:00
matlabbe d8ebbc2645 CameraK4A: rectifying color image (this improves a lot visual odometry accuracy) 2020-12-13 15:27:17 -05:00
matlabbe d700d09339 DataRecorder tool: interface changed to use config file (#661) 2020-12-13 12:42:58 -05:00
matlabbe 3104dff006 Update README.md 2020-12-13 11:10:22 -05:00
matlabbe 839045a538 package.xml: 0.20.7 2020-12-12 19:05:06 -05:00
matlabbe a824945816 package.xml: removed libvtk-qt as there are conflicts on noetic with libpcl-dev (which is using vtk7) 2020-12-12 17:32:30 -05:00
matlabbe 1acf8ff193 RegIcp: don't assert if normals cannot be computed properly before doing complexity check, just reject the transform 2020-12-12 16:53:07 -05:00
matlabbe 51826c9a97 RegIcp: fixed KDTreeMatcherIntensity build error on Mac. 2020-12-11 17:22:29 -05:00
matlabbe 7a5d04062d vtk8: disabled vtkOutputWindow 2020-12-11 17:05:37 -05:00
matlabbe 049238dd59 Gui: added L515 icon 2020-12-11 09:56:17 -05:00
42Max42 3271723034 superpoint, fixing slow convert after cnn (#659)
* fixing slow convert after cnn

* restoring cmake
2020-12-11 09:27:18 -05:00
matlabbe da8e76ffed rtabmap-matcher: added --calibration_to option (to use a different calibration file for the second image). 2020-12-05 13:21:58 -05:00
matlabbe 3131474102 Added Db/TargetVersion parameter (#652) 2020-12-03 15:45:40 -05:00
matlabbe 3ffc8ce73f DBViewer: enabled Reject button on landmark links 2020-11-30 23:17:47 -05:00
matlabbe ee44adeb1f fixed #648 (build error without OctoMap dependency) 2020-11-30 12:33:08 -05:00
matlabbe 96c1c81e22 fixed build with older libpointmatcher versions <10300 2020-11-29 19:30:30 -05:00
matlabbe 0022b6b993 ExportCloudsDialog: added colormap option when showing scans 2020-11-28 18:02:54 -05:00
matlabbe 721e046f5d fixed build 2020-11-28 17:36:42 -05:00
matlabbe d733029565 Increased version to 0.20.7. OdometryF2M: added support for intensity field, removed ignored key frames when there is low scan complexity. RegistrationIcp: added Icp/PMMatcherIntensity, Icp/PointToPlaneGroundNormalsUp and Icp/PointToPlaneLowComplexityStrategy parameters. Rtabmap: when graph optimized from end, increased optimization error before warning that resulting map correction is not identity (this could happen with GTSAM as the root is not perfectly fixed). CloudViewer: added coordinate frame scaling option, added rainbow colormap option for scan intensity. DBViewer: fixed local proximity merged scans not shown modified after refining those links, show intensity, fixed constraints view not updated after rejecting a link. MainWindow: added intesity support with odometry scans. 2020-11-28 17:28:34 -05:00
matlabbe 7859313beb AppVeyor: updated realsense2 sdk to 2.40. CameraRealSense2: When GlobalTimeSync option is off, don't wait 35 ms for imu (and fails), just take the latest one directly (https://github.com/introlab/rtabmap/issues/614#issuecomment-732244439). 2020-11-23 11:36:27 -05:00
matlabbe 80199f23b5 RegIcp: complexity, checking if second eigen value is also under Icp/PointToPlaneMinComplexity to limit to only one axis. DbViewer: fixed refine link with scans having RGB channel. 2020-11-22 19:32:01 -05:00
matlabbe bce7ae6acd Fixed GTSAM reference frame yaw drift over time when gravity links are used 2020-11-22 16:40:30 -05:00
matlabbe f88845e138 fixed #643 2020-11-22 14:29:05 -05:00
matlabbe bdc7be40b4 Fix for previous commit https://github.com/introlab/rtabmap/commit/e4cb59b74d69887fd67700420d408db5a6850663 (otherwise imu are ignored if globalTimeSync is off) 2020-11-22 12:38:21 -05:00
matlabbe e4cb59b74d Added suggestion from https://github.com/introlab/rtabmap/issues/614#issuecomment-731769818 2020-11-22 12:32:39 -05:00
matlabbe dab407e5b9 fixed https://github.com/introlab/rtabmap/commit/ad44b65a28c0bb16add80a3d0afb9c721f84ba68#commitcomment-44427459 2020-11-22 11:10:35 -05:00
matlabbe 98a499b603 Optimizer: fall back on g2o or gtsam first if one or the other is not available (instead of going TORO). ExportClouds: added ceiling and floor filtering options. 2020-11-22 01:23:08 -05:00
matlabbe f5d7dc2814 PreferencesDialog: Added Marker/MaxRange and Marker/MinRange parameters to UI. 2020-11-21 17:23:41 -05:00
matlabbe ab1aa5578a Fixed build 2020-11-21 17:12:09 -05:00
matlabbe ccbdb586da DbViewer: Added datbabase path to window title 2020-11-21 16:37:40 -05:00
f467f2af7f Added Marker/MaxRange and Marker/MinRange parameters (#630)
* ADD 3 meter limit for marker detections

* ADD Marker/MaxRange and Marker/MinRange parameters for controlling marker detection
ADD ctags ignore

Co-authored-by: John Paul Soliva <soliva@seaos.co.jp>
Co-authored-by: Tim Fronsee <tfronsee21@gmail.com>
2020-11-21 16:18:22 -05:00
matlabbe 7c4d2bbdf4 DbViewer: before resetting all changes, added a confirmation message box! 2020-11-21 16:15:27 -05:00
matlabbe fb206b4f1e DbViewer: fixed scan disappearing after editing constraint 2020-11-21 14:35:29 -05:00
matlabbe ddecefbb9c 💄 2020-11-21 12:34:17 -05:00
matlabbe ad44b65a28 Allow partial support for AliceVision v2.3.0 (see #564 for remaining issues) 2020-11-20 13:42:56 -05:00
matlabbe fdaaa6ccfa Fixed bug L500 gyro/acc not detected (#629) 2020-11-19 13:49:10 -05:00
matlabbe 34e1af7e22 RealSense2: added error message for L515 if resolution is not 640x480 30 fps (#629) 2020-11-19 10:38:15 -05:00
matlabbe 54e2688a1d Fixed build with pcl > 1.11.1 (#641) 2020-11-14 16:52:01 -05:00
matlabbe f9abcf9e35 fixed opencv2 build 2020-11-14 14:41:37 -05:00
matlabbe 01eb57f293 CameraImages: added configForEachFrame option (added to GUI too). CameraThread: for decimation, if depth is smaller than RGB, RGB is decimated first and if the resulting RGB image is smaller than the original depth, we then decimate the depth. 2020-11-14 13:39:12 -05:00
matlabbe 7be22d1b67 Added check to make sure input odometry poses are invertible. Source/DB: added stereo to depth option. 2020-11-06 21:37:59 -05:00
matlabbe 4b527f9c36 Update .appveyor.yml 2020-11-06 18:56:32 -05:00
matlabbe 4d965c2089 Update .appveyor.yml 2020-11-06 18:18:06 -05:00
matlabbe 47cbd633c3 Update .appveyor.yml 2020-11-06 18:11:29 -05:00
matlabbe b95537a680 Added c++11 definition when latest libpointmatcher is found 2020-11-06 16:37:29 -05:00
matlabbe e102243f0e Fixed weight=-8 bug when moving rehearsed node to trash 2020-11-06 14:47:10 -05:00
matlabbe e7a2f206a0 Gui: fixed warning scan not found when uncompressing data. Don't disable Mem/UseOdomFeatures checkbox anymore in monitoring mode (ROS). 2020-11-05 15:50:05 -05:00
matlabbe d04b1a13be multiband: add multi-camera support. rtabmap-export: updated options (now supporting creating point cloud from scans). 2020-11-04 14:02:18 -05:00
matlabbe 92b1dabf1c MainWindow: avoid uncompressing images/scans if they are not shown 2020-11-03 16:12:43 -05:00
matlabbe e269067d4c Texturing: add distanceToCamPolicy option 2020-11-03 16:11:37 -05:00
matlabbe 596cd10b69 Fixed -lBoost::timer not found on ubuntu18.04/arm64 (#587) 2020-11-01 13:08:55 -05:00
matlabbe 6a730b51c7 GUI-Preferences: disabled Daisy feature option on OpenCV 2 2020-11-01 13:01:23 -05:00
matlabbe 4ecf37a3ab fixed build with OpenCV 2.4 2020-11-01 12:49:21 -05:00
matlabbe 99275fba1d Added Daisy descriptor. ORB: updated default parameters. Making ORBOctree using ORB parameters. Updated Vis/CorNNDR default from 0.6 to 0.8 (increase number of matches with binary descriptors, increase slightly feature matching time with float descriptors). Note that jfr2018 scripts have been updated to use old value 0.6. rtabmap-info: show descriptor dimension and type. 2020-11-01 11:28:59 -05:00
matlabbe 25c2a51ee3 fixed windows build 2020-10-29 18:03:36 -04:00
matlabbe 600484e12c Update .appveyor.yml
#624
2020-10-29 11:52:25 -04:00
matlabbe 8878d9fcdf Update .appveyor.yml
#624
2020-10-29 11:44:31 -04:00
matlabbe 72e1649cdd DataRecorder: added imu filtering by default 2020-10-22 18:02:24 -04:00
matlabbe afbc0edbd6 Local occupancy grid: fixed empty obstacles with scans having intensity channel when Grid/RangeMax is used. 2020-10-21 15:38:19 -04:00
matlabbe fbc30042c4 Fixed biggest index/min/max when Grid/MaxGroundHeight is set (http://official-rtab-map-forum.67519.x6.nabble.com/Comparison-between-realsense-D435-vs-T265-vs-T265-D435-dual-setup-td6456i20.html) 2020-10-18 15:56:13 -04:00
matlabbe a4da1e14b4 SIFT: fixed SIFT not extracted with OpenCV >=4.4 and >=3.4.11 when nonfree is false 2020-10-17 20:34:24 -04:00
matlabbe 3047b7da6b CameraRealSense2: update for L515 support 2020-10-17 19:57:27 -04:00
matlabbe bbb3c56008 Fixed android build 2020-10-16 14:55:50 -04:00
matlabbe f71f00277c DbViewer::AddConstraint: don't ask ofr manual constraint if already aborted previous question (when Reg/Strategy=1). 2020-10-12 17:41:06 -04:00
matlabbe 0e5ec91280 DbViewer: added option to ignore landmarks. Show landmark id in Constraints View. 2020-10-12 15:29:20 -04:00
matlabbe 3aae79270f Output an error if a timestamp file is missing instead of asserting #613 2020-10-12 14:30:57 -04:00
matlabbe 1b4a992b55 Merge branch 'master' of https://github.com/introlab/rtabmap into devel 2020-10-12 13:16:08 -04:00
matlabbe 384b120d2e Fixed landmark ignored when Rtabmap/StartNewMapOnLoopClosure is true and a loop closure is rejected (before graph optimization) 2020-10-12 13:05:14 -04:00
matlabbe 304c365ae6 Kp/ByteToFloat: Changed default of false
Based on http://official-rtab-map-forum.67519.x6.nabble.com/ZED2-rtabmap-loop-closure-and-twisted-map-tp6986p7002.html
2020-10-12 11:04:59 -04:00
matlabbe d5572d03ad DbViewer: added checkbox to enable Add for nodes not linked to graph 2020-10-09 12:15:33 -04:00
matlabbe 6d552b7873 DbViewer: fixed depth of features not shown 2020-10-09 11:10:48 -04:00
matlabbe 32eb266c79 fixed CMP0020 cmake warning 2020-10-09 11:10:21 -04:00
matlabbe 2cb509c825 DbViewer: manual constraints can now be added (http://official-rtab-map-forum.67519.x6.nabble.com/Manually-adding-modifying-node-constraints-td6983.html) 2020-10-07 15:41:13 -04:00
matlabbe 168c87b5ba Added statitic Timing/RAM_estimation/. Updated VWDictionary::getMemoryUsed(). 2020-10-05 22:11:28 -04:00
matlabbe a80e062bef Fixed build error in Trusty 2020-10-05 18:17:18 -04:00
matlabbe 9e321971ef Removed debug log 2020-10-05 17:49:26 -04:00
matlabbe 8260733b11 fixed detectMoreLoopClosures when RGBD/LocalBundleOnLoopClosure is true 2020-10-05 17:47:13 -04:00
matlabbe bbccbd63e4 Increased version to 0.20.5
Refactored how features are stored in Signature (significative memory optimization, causing major refactoring in Memory, RegistrationVis, OdometryF2M)
FLANN: optimized memory usage when Kp/IncrementalFlann is false
Added memory usage functions
Added statistics Loop/Visual_inliers_ratio/ and Memory/RAM_estimated/MB
EpipolarGeometry: templated findPairs functions
graph::filterLinks: added inverted option
LocalBundleOnLoopClosure: Force to use only neighbor links
MainWindow: fixed max depth filtering for map's features
Rtabmap::getSignatureCopy() fixed links not returned
Added UPlot::getAllCurveDataAsText() function.
DbViewer: fixed features not rendered in right view when failing ro refine a constraint
report: added --export and --export_prefix options (to export figures data)
2020-10-05 17:34:32 -04:00
matlabbe bedc771fa4 Rtabmap: added getNodesInRadius() public functions 2020-09-28 12:03:42 -04:00
matlabbe 933ac736f1 Increased version 0.20.4. Added parameter Kp/ByteToFloat (default true to use less memory with kdtree and binary descriptors). Memory/Sqlite3: Setting weight to -9 for invalid nodes (to make sure they are not reloaded from database, to fix a graph reduced issue). Added 12-SURF/FREAK detector approach. rtabmap-info: added number of nodes in each sessions. 2020-09-28 10:29:14 -04:00
matlabbe c5158cade5 Fixed loop closure rejected if the camera on the robot changes orientation accordingly to base frame (http://official-rtab-map-forum.67519.x6.nabble.com/Mapping-with-multiple-stereocameras-localization-with-multiple-monochrome-monocular-cameras-tp6647p6953.html). The reason why that check was there was because ICP flipping 180 deg in some cases, but should be already detected with that commit https://github.com/introlab/rtabmap/commit/7a1cf84b0845f430fdaf0800c0960c9795a73ec4#diff-b65a61c23197f7ff77a877f62b630b2cR283. 2020-09-27 14:38:36 -04:00
matlabbe eef0a23b1b Reprocess: added --skip option (to skip frames when reprocessing). Rtabmap: always save Loop/Map_id/ stat. UPlot: export NaN insted of NA for invalid values (compatible with octave). GraphViewer and ImageView: added support for PDF output format, also changed default directory to User's Pictures standard folder. 2020-09-21 19:32:48 -04:00
matlabbe 3d33370e4c DbViewer: fixed error log when showing landmarks in Constraints view. 2020-09-15 17:12:00 -04:00
matlabbe 4e6e404951 Fixed "[Setjac] infinite jac" error when Vis/ForwardEstOnly is false. OptimizerG2O: Added a check to ignore invalid 3d points. 2020-09-15 15:18:49 -04:00
matlabbe 29368ebdb3 report: fixed database order in localization results 2020-09-15 14:06:23 -04:00
matlabbe a24211583d Rtabmap: init Bayes prediction when loading a database 2020-09-11 10:55:33 -04:00
matlabbe d50b33a7b8 Preferences: updated warnings for free sift (#596) 2020-09-10 17:56:49 -04:00
matlabbe a689d8a23f report: fixed how localization stats are split against localization sessions only 2020-09-10 14:09:27 -04:00
matlabbe bd80811ea1 Stats: added Loop/Distance_since_last_loc 2020-09-10 14:07:53 -04:00
matlabbe cabf03af44 Memory: fixed keypoints3d wrongly copied when not using odom features 2020-09-08 21:24:47 -04:00
matlabbe f93cdc31a6 Gui/source/K4A: added more description 2020-09-04 15:12:05 -04:00
matlabbe e0973fea92 CameraK4A: added imu support with playback. Fixed windows build error. 2020-09-04 14:10:32 -04:00
matlabbe 49cb470b8d CameraK4A: refactored to unify playback and real device code. Fixed ir option (with rectification). 2020-09-04 12:48:18 -04:00
matlabbe d2784095a3 Added K4A status on --version. About: added Mynteye status 2020-09-04 10:39:15 -04:00
matlabbe 1db17dd118 rtabmap-report: added loc_delay option. Db info: added unused space 2020-09-03 15:23:48 -04:00
matlabbe 23d8353540 Rtabmap::detectMoreLoopClosures, use optimized graph as guess if RGBD/ProximityOdomGuess is true. Reprocess: added options to generate scan from depth image and/or pre-process input scans. 2020-08-28 16:24:07 -04:00
matlabbe 96a628877c reprocess: when merging databases, return number of sessions merged when program exists. export: added --save_in_db option. 2020-08-28 12:29:16 -04:00
matlabbe 24052a6ebe fixed pcl::getAngle3D not found error on latest pcl version (https://github.com/PointCloudLibrary/pcl/commit/6df3e602a72ea16657f901c9a6911d95b263ba08#diff-8e08415b9972a447d115dbca3f8fa0a1) 2020-08-25 10:56:30 -04:00
matlabbe 775c9318d3 Fixed Too large rotation detected message 2020-08-21 15:57:28 -04:00
matlabbe f263d560b4 OdomF2M: fixed complexity null for first scan is not having normals already 2020-08-21 14:32:08 -04:00
matlabbe 729f96f467 TORO: added warnings when prior or landmark links are detected 2020-08-21 11:26:22 -04:00
matlabbe 8d63e9eae1 Fixed 'cannot find -lBoost::thread' build error when building only with libpointmatcher dependency 2020-08-14 12:25:03 -04:00
matlabbe 39f68c44c6 Recovery: set back database in mapping mode after being saved in localization mode 2020-08-03 13:46:42 -04:00
matlabbe 0a9d237ac2 0.20.3: CameraRealSense2: Fixed D435i accel/gyro profile selection to avoid crash. Fixed Integrated D415 fix (#469) 2020-08-01 20:29:47 -04:00
matlabbe 07d21e6b03 VINS update log: printf to UDEBUG 2020-07-30 12:34:58 -04:00
matlabbe 53a759e2da Fixed missing vins usage with run_euroc_datasets.sh 2020-07-29 11:50:53 -04:00
matlabbe 6741355842 Ignore invalid GPS values (NaN #570) 2020-07-29 10:39:34 -04:00
matlabbe 1460c56254 Merge branch 'melodic-devel' of https://github.com/introlab/rtabmap 2020-07-12 15:02:00 -04:00
matlabbe dec135a3fb package.xml: added explicitly libvtk-qt dependency for debian build error 2020-07-12 14:59:40 -04:00
matlabbe 9edd9b741d tango-api19: fixed docker build 2020-07-10 22:16:16 -04:00
matlabbe 43eba76a20 docker: updated tango-api19 image 2020-07-10 15:26:59 -04:00
matlabbe bf45a0cba2 docker: fixed arcore not correctly extracted 2020-07-10 09:04:38 -04:00
matlabbe 4be07fc3e9 fixed tango build without arcore support 2020-07-10 08:58:56 -04:00
matlabbe 4e32e8846c fixed build error 2020-07-08 21:34:41 -04:00
matlabbe 6468245317 Reprocess: added loc stats in motion, added option to export odom and loc poses in g2o format 2020-07-08 21:25:14 -04:00
matlabbe 169b79215d Memory::computeIcpTransformMulti() added support for 3d scans with RGB channel (L515) 2020-07-08 13:43:28 -04:00
matlabbe 4a09c4bdcf Odometry: fixed Reg/Force3DoF ignored if filters are not used 2020-07-08 10:03:54 -04:00
matlabbe 3505611fb5 reprocess: set Mem/UseOdomFeatures to false if Kp/DetectorStrategy or Vis/FeatureType is overwritten (#566) 2020-07-06 13:31:01 -04:00
matlabbe 55228aa574 Update README.md 2020-07-02 21:43:10 -04:00
matlabbe e800662bac Fixed build with OpenCV >= 3.4.11 2020-07-02 16:29:23 -04:00
matlabbe 33e9abdfad Mac: fixed crash when discarding a signature (not moving enough) with self refenced links. Fixed link error with realsense2 library on Mac. 2020-07-02 12:54:43 -04:00
matlabbe cd10cafd0e Windows: fixed CameraRealSense2 driver freezing on close. 2020-07-01 20:58:04 -04:00
matlabbe 736cf0efc7 Windows: fixed stamp now() issue 2020-07-01 16:53:57 -04:00
matlabbe 4f6d8b1fbe Windows: add depthengine_2_0.dll plugin when packaging with K4A support 2020-07-01 14:46:37 -04:00
matlabbe 8fa216bd9d Fixed default odom gravity sigma value to -1. Preferences: set 720p by default for K4A driver 2020-07-01 14:04:19 -04:00
matlabbe 661a05b0da CameraMyntEye: fixed M_PI not defined error 2020-06-30 23:36:12 -04:00
matlabbe 0809946c66 Windows: Fixed stereoRectifyFisheye.h 'cannot convert from cv::Mat to CvMat' compilation error with opencv >=3.4.4. Fixed k4a/k4atypes.h not found on guilib compilation. 2020-06-30 23:18:31 -04:00
matlabbe 4857d43146 android: ui update. fixed arcore java driver not stopping in background 2020-06-29 20:41:59 -04:00
matlabbe b7ada1992e android: added occlusion detection using arcore depth api (for FPS view). Added depth from motion option in Mapping options. 2020-06-29 20:25:58 -04:00
matlabbe 2ee3445728 Docker: updated arcore 1.18 download link 2020-06-29 15:35:14 -04:00
matlabbe 4142ff003c Added AR mapping mode (select ARCore ndk driver and set first person view) 2020-06-29 15:24:35 -04:00
matlabbe 542f06ec24 ARCore: features from arcore are used directly for keypoints 2020-06-29 15:08:24 -04:00
matlabbe dacf724ea6 Rtabmap::addLink() support multi-session 2020-06-25 13:56:01 -04:00
matlabbe 274903dd63 Rtabmap::getSignatureCopy() added withWords and withGlobalDescriptors options 2020-06-22 22:56:25 -04:00
matlabbe c19f81ac12 Memory::getNodeData() removing not wanted data if the node with all its data has been found in working memory. 2020-06-22 22:29:26 -04:00
matlabbe 846bd59d0b Rtabmap::addLink() removed an error log that is actually a debug log. 2020-06-22 21:53:22 -04:00
matlabbe 6e1f07e097 CameraK4A: fixed IMU local transform, fixed some compilation warnings. 2020-06-22 19:42:55 -04:00
matlabbe 1ca2c25a10 DbViewer: fixed empty from scan when refining proximity link by space 2020-06-22 13:07:27 -04:00
matlabbe c5ec4f337b util3d::segmentObstaclesFromGround() fixed no ground returned if maximum ground height is set and the biggest plane was not under that height (e.g., ceiling having more points than ground) 2020-06-18 21:30:43 -04:00
matlabbe 554b08256b Statistics: Added Odometry_correction_acc_* 2020-06-18 14:47:00 -04:00
matlabbe a2b0de2a4d MacOSX bundle: fixed ui native style with Qt>=5.10 2020-06-18 12:09:26 -04:00
matlabbe fb6659e29d CloudViewer: reduced ambient lighting for textureMesh with VTK>=7 2020-06-18 11:28:53 -04:00
matlabbe db00f55981 CloudViewer: fixed texture not shown with VTK>=7 2020-06-18 10:59:42 -04:00
matlabbe ffdb2eb855 Docker: added focal image, fixed bionic image not building with alicevision. Updated travis with focal build. 2020-06-09 21:15:54 -04:00
matlabbe 13679cc52a Export tool: fixed generated texture output directory 2020-06-09 12:58:55 -04:00
matlabbe 4769fc235f Refactoring: set default local transform for camera drivers to opticalRotation. Added CameraModel::opticalRtotation() static function for convenience. Added CameraModel::load() from file directly for convenience. Added Camera::initFromFile() for convenience. Transform: Added opengl_T_rtabmap() and opengl_T_rtabmap() functions for convenience (convert back and forth between rtabmap world and opengl world coordinate frames) 2020-06-08 11:40:47 -04:00
matlabbe ff5695878c Rtabmap::init() added loadDatabaseParameters argument for convenience (default false to be backward compatible) 2020-06-08 10:35:12 -04:00
matlabbe 6029b6283d Rtabmap: Refactored how fake odom is generated in localization mode when no odom is provided. Trigger new map in localization mode also clears last localization pose if RGBD/SavedLocalizationIgnored is true. 2020-06-08 10:14:21 -04:00
matlabbe 86ac63ab19 UPlot: changed float to qreal (double). Added UPlot::frameData() function. 2020-06-07 11:55:27 -04:00
Thomas Kircher de5610bd08 Added preferences for Azure Kinect camera (#559)
* Added Kinect for Azure menu option

* Reintegrated Kinect for Azure initialization code, fixed previous GUI commit

* Added ifdefs to fix build

* Added preliminary K4A device support

* Edits to K4A camera implementation

* K4A minor initialization fix

* Typo

* Another initialization fix

* Update CameraRGBD tool to display K4A camera output

* K4A added model parameter so we can create maps

* Added combo boxes for K4A options

* Functionalized combo boxes for K4A options

* Finished adding K4A preferences
2020-06-04 11:34:37 -04:00
matlabbe 7a9a5d2ef9 CloudViewer: updated camera clipping 2 2020-06-03 14:50:59 -04:00
matlabbe b6d4c6f024 CloudViewer: fixed camera clipping the grid 2020-06-03 13:41:36 -04:00
matlabbe ff3c6c8e06 Update README.md 2020-06-02 19:59:21 -04:00
matlabbe e2007a8f82 CloudViewer: fixed build with vtk<6 2020-06-01 22:18:45 -04:00
matlabbe bda18bc517 CloudViewer: added EDL shading option 2020-06-01 21:44:42 -04:00
matlabbe d00717b068 package.xml: removed explicit dependency to libvtk-qt (https://github.com/introlab/rtabmap/issues/557) 2020-06-01 11:42:35 -04:00
matlabbe c7be9a23ee OdometryF2M: refactored imu buffer 2020-05-31 14:33:20 -04:00
matlabbe caffb56246 DBViewer: fixed StereoSGBM panel not shown. Odometry: fixed Odom/GuessSmoothingDelay type 2020-05-31 13:26:54 -04:00
matlabbe d5cfd8013d CameraMyntEye: added setIrControl() 2020-05-31 12:17:14 -04:00
matlabbe 415a2778f1 Added Features2d::limitKeypoints() with grid options. Odometry: if imu is provided and no guess is provided, the change of orientation of imu is used for rotation guess (overwrite rotation from Odom/GuessFromMotion). OdometryInfo: added gravity errors when imu is used. Preferences: added a second GravitySigma parameter (overwritting Optimizer/GravitySigma for odometry is not negative) for F2M odometry panel. 2020-05-31 11:22:12 -04:00
matlabbe 6e55525a7b Memory::getNeighborsId() fixed no link returned when looking in database 2020-05-30 09:20:32 -04:00
matlabbe 7eae992d6f rtabmap-report: fixed map.at() error if the database as empty statistics 2020-05-28 21:21:31 -04:00
matlabbe 2509b6ee09 Statistics: added MapToOdom and MapToBase stats 2020-05-28 21:04:01 -04:00
matlabbe 45ddce938a CameraMyntEye/GUI: added manual/auto exposure option (default auto). Rtabmap: refactored warning when RGBD/OptimizeFromGraphEnd changes state. 2020-05-28 19:50:02 -04:00
matlabbe 6e0081e248 MainWindow: made mynteye action checkable. 2020-05-28 14:04:10 -04:00
matlabbe bf39c5295b Ported PCL 1.11 deprecated changes to PCL 1.10 (#550) 2020-05-27 17:45:16 -04:00
matlabbe 8842d0c0e3 fixed isfinite -> std::isfinite 2020-05-27 16:39:50 -04:00
matlabbe 511be5f663 Fixed build with pcl 1.11 (#550). Fixed pcl 1.11 warnings (boost->std). 2020-05-27 16:35:33 -04:00
matlabbe ae5ce029d6 Fixed SIFT build issue between OpenCV 4.3.0 and OpenCV 4.3.0-dev 2020-05-27 10:35:18 -04:00
matlabbe 798466bb05 Increased ros package version to 0.20.0. Parameters: fixed default feature detector when xfeatures2d is not found 2020-05-26 22:44:44 -04:00
matlabbe 0902ccc340 Updated error message when SBA is done on multicam setup. 2020-05-26 11:04:23 -04:00
matlabbe 208f1e5b7c OdomF2M: fixed complexity check on 2d scans (https://github.com/introlab/rtabmap_ros/issues/412) 2020-05-25 20:07:58 -04:00
matlabbe b40d9610ed Preferences: Fixed xfeatures2d features not available without nonfree on OpenCV >= 3.4.2 (https://github.com/introlab/rtabmap_ros/issues/422) 2020-05-25 17:31:13 -04:00
Thomas Kircher 35385e299d K4A mapping working now (#554)
* Added Kinect for Azure menu option

* Reintegrated Kinect for Azure initialization code, fixed previous GUI commit

* Added ifdefs to fix build

* Added preliminary K4A device support

* Edits to K4A camera implementation

* K4A minor initialization fix

* Typo

* Another initialization fix

* Update CameraRGBD tool to display K4A camera output

* K4A added model parameter so we can create maps
2020-05-25 11:46:16 -04:00
matlabbe 6acfc62196 CloudViewer: adjust frustum fov based on camera model (https://github.com/introlab/rtabmap_ros/issues/419) 2020-05-24 11:13:13 -04:00
matlabbe eb9999d7b1 Rtabmap::addLink() supporting localization mode. MainWindow: fixed flickering camera frustum. 2020-05-21 21:26:29 -04:00
matlabbe 69a2aacc8e Parameters: added SIFT/RootSIFT parameter. 2020-05-21 17:09:20 -04:00
Thomas Kircher 013bd0c72a K4A device, fixed some stale edits (#553)
* Added Kinect for Azure menu option

* Reintegrated Kinect for Azure initialization code, fixed previous GUI commit

* Added ifdefs to fix build

* Added preliminary K4A device support

* Edits to K4A camera implementation

* K4A minor initialization fix

* Typo

* Another initialization fix

* Update CameraRGBD tool to display K4A camera output
2020-05-20 19:36:15 -04:00
Thomas Kircher 89ece8cd4e Preliminary K4A device support (#552)
* Added Kinect for Azure menu option

* Reintegrated Kinect for Azure initialization code, fixed previous GUI commit

* Added ifdefs to fix build

* Added preliminary K4A device support
2020-05-20 15:31:30 -04:00
matlabbe 360a153565 Parameters: Renamed SuperGlue group to PyMatcher group. Added OANet python script. 2020-05-20 09:45:39 -04:00
matlabbe 63d40b2240 Fixing trusty build 2020-05-19 18:06:20 -04:00
matlabbe cb60443a33 Fixing OpenCV<3 build 2020-05-19 15:44:41 -04:00
matlabbe 609d45ac9b 💄 2020-05-19 15:33:32 -04:00
Thomas Kircher b542d6a0db Added Kinect for Azure menu option (#551)
* Added Kinect for Azure menu option

* Reintegrated Kinect for Azure initialization code, fixed previous GUI commit

* Added ifdefs to fix build
2020-05-19 15:03:36 -04:00
matlabbe c7b84c60bc Parameters: added Mem/StereoFromMotion (default false) and RGBD/ProximityOdomGuess (default false). Visual proximity detection is done before computing the loop closure transform (the later is ignored if visual proximity succeeded with a node close to loop closure, add Loop/Suppressed_hypothesis_id statistics to know when this happens). Changed Loop/Map_correction to Loop/Odom_correction (to better see the actual jumps of localization about /base_link frame, not /odom frame). util3d::generateWords3DMono() is now using openCV's implementation of five-point algorithm (this fixed some cases for which the older approach couldn't find any solution). UPlot: added scrolling area on the legend, added global legend option to show all curve statistics (mean, stddev,max). MainWindow's open dialog: reopen last directory when reopening a different database. ParametersToolBox: show default parameter value in tooltip. rtabmap-report: add --start option. rtabmap-reprocess: show details about proximity and loop detections, reset all localization statistics after changing database. 2020-05-19 15:01:50 -04:00
matlabbe 55509c6c27 Fixed build with OpencV 2.4 and Qt4 2020-05-13 15:15:52 -04:00
matlabbe 00695731fe SuperGlue: added traceback when there is an error with python. 2020-05-13 11:18:34 -04:00
matlabbe 09d2f7d232 Fixed android build 2020-05-12 22:04:03 -04:00
matlabbe e906b40e50 Fixed build with opencv < 3.4.1 2020-05-12 10:26:08 -04:00
matlabbe 1b675c3dcb Preferences: fixed SuperGlue/Indoor widget not found 2020-05-11 14:10:49 -04:00
matlabbe d2673ed2fa Added GMS matching approach (Vis/CorNNType=7). Added GMS/ parameters. Added SuperGlue/Indoor parameter. ImageView: updating feature and line colors directly when changing color (option menu), fixed items already added to scene warning when switching to GraphicsView. 2020-05-11 13:23:26 -04:00
matlabbe cc9fd439fe SuperPoint: updated descriptor normalization process to match exactly the implementation in SuperGlue. generateWords3DMono: use variance at 25% instead of 50% of the sqrd variance vector (to do the same than with PnP), also fixed return camera transform to include local transform of the camera model. rtabmap-matcher: updated default parameters when no depth images are used, added reproj error in title bar. 2020-05-10 14:13:41 -04:00
matlabbe fbdc3780c7 Freenect: fixed imu local transform. Preferences: show imu filters with freenect driver. 2020-05-09 23:13:39 -04:00
matlabbe c44837a4cb Fixed build without SuperGlue 2020-05-09 21:41:38 -04:00
matlabbe 91285e5e97 Added SuperGlue support (Vis/CorNNType=6). Added rtabmap-matcher tool. DBViewer: show matches/inliers when refine also fails. SIFT: make sift always available on OpenCV 4.3.0 (#538). Parameters: changed SPTorch prefix to SuperPoint, replaced Vis/CorCrossCheck by Vis/CorNNType=5. 2020-05-09 21:13:41 -04:00
matlabbe abc3ebee8c fixed #538 2020-05-09 11:48:06 -04:00
matlabbe 1af139134e Deprecated Rtabmap::get3DMap(), use Rtabmap::getGraph() instead with setting to true the data flags. Rtabmap::getGraph() now ignores children nodes. 2020-05-06 08:04:58 -04:00
matlabbe 7d377d26df Added Rtabmap::getSignatureCopy() 2020-05-05 13:26:40 -04:00
matlabbe 7041d5fd34 Fixed #541 2020-05-03 22:59:35 -04:00
matlabbe c19da22ca4 0.20: added GlobalDescriptor table in database 2020-05-03 21:46:25 -04:00
matlabbe 50c3bb7ce9 fixed #540 2020-05-03 14:05:14 -04:00
matlabbe 0a4d0038cb Preferences dialog: fixed missing Vis/CorCrossCheck checkbox 2020-05-02 11:03:17 -04:00
matlabbe d14efea4ac Added Vis/CorCrossCheck parameter (to use BFMatcher with crosscheck option instead of knn with NNDR for features matching). DBViewer: after refine or add constraint, lines indicating feature correspondences are now shown with different color if they are inliers. Re-enabled saving/loading settings of the ImageViews (feature color, line color, transparency...). 2020-05-01 22:12:56 -04:00
matlabbe 45223b306a Increased SPTorch/Threshold decimals for more fine tuning in DBViewer 2020-05-01 19:59:28 -04:00
matlabbe 3e9cff4053 fixed build with opencv 4.3 2020-05-01 09:51:54 -04:00
matlabbe 46886f2637 Report: added invert and ids options. Reprocess: show node id along map id when processing. 2020-04-30 17:00:09 -04:00
matlabbe 40804d9120 Statistics: added x,y,z map corrections. Report: added options --stats to show available statistics to plot in a database 2020-04-30 15:48:47 -04:00
matlabbe 803c99cee2 RegVis: fixed Vis/MaxDepth and Vis/MinDepth ignored when features are already extracted. 2020-04-30 15:07:32 -04:00
matlabbe 5d16ae8cfe DBViewer: fixed calibration not found on refining without re-extracting features, fixed visualized ids switched on refine in some cases, fixed clouds not shown in constraints view after refine without re-extracting features 2020-04-30 14:17:46 -04:00
matlabbe ace93b0356 GUI: check mynteye when selected 2020-04-30 01:00:17 -04:00
matlabbe 14ec619b1e Added MYNT EYE S support. Fixed StereoCameraModel rectification not done with non-square images, also updated to support fisheye model. 2020-04-30 00:57:47 -04:00
matlabbe b3eee0d7bf android: fixed yuv conversion bug on some devices, updated default driver based on which one is available and built with it. 2020-04-29 12:18:02 -04:00
matlabbe 37e0860b0c android: Fixed upload button not visible in Sketchfab activity, webview can be canceled 2020-04-27 17:35:06 -04:00
matlabbe be57c2752d Fixed gravity links not added for optimization when both prior and gravity links are added to same nodes 2020-04-26 23:45:32 -04:00
matlabbe 1a3c90e898 cleanup some debug logs 2020-04-26 14:57:27 -04:00
matlabbe 06482d2378 ARCore: when tof camera is not available, use arcore point cloud as keypoints 2020-04-26 14:48:48 -04:00
matlabbe 3abdd22031 android: fixed state locked in processing after saving 2020-04-26 09:40:50 -04:00
matlabbe 66fca15cc6 Added rtabmap-info console tool 2020-04-24 13:45:41 -04:00
matlabbe 0c04b77cd7 Android: simplified default workflow (open -> scan -> optimize/export -> save) 2020-04-24 09:22:14 -04:00
matlabbe 6bb6178ae5 android: fixed Resume disabled when returning from Visualization 2020-04-24 08:23:17 -04:00
matlabbe 4ad92f0261 Docker: fixed android-## cloning branch 2020-04-24 07:33:48 -04:00
matlabbe bc8d811f69 Dictionary: fixed L2SQR format for GPU BF 2020-04-23 22:56:42 -04:00
matlabbe e8be3f21fa SuperPoint: fixed nms bug 2020-04-23 20:06:48 -04:00
matlabbe 31e5f7804e DbViewer: set horizontal layout by default 2020-04-23 15:27:31 -04:00
matlabbe 9b54aeee22 Android: set estimation type to default PnP 2020-04-23 15:13:58 -04:00
matlabbe 00d8375a2e RGBD/SavedLocalizationIgnored: if true, it is now starting at the origin (0,0,0) instead of null (not linked to graph). 2020-04-23 11:57:01 -04:00
matlabbe 046e0b7888 updated xenial tango docker file 2020-04-23 08:08:57 -04:00
matlabbe 35074f6d9f DBViewer: fixed missing parameter groups in Core Parameters. MainWindow: disabled frames by default. 2020-04-22 18:30:42 -04:00
matlabbe 94360e19e0 DBReader: changed maxFrames option to stopId and startIndex to startId. Reprocess: added options to start and stop at specific ids in the database. 2020-04-22 16:20:29 -04:00
matlabbe 012439aa0b Tango refactoring (#534)
* Created general CameraMobile interface. Tango is now optional. Camera is disabled on visualizaion (battery saving).

* Working android app on non-tango android phones (tested on x86_64 android emulator).

* fixed typo

* android: updated tango not available msg

* android: fixed build with latest android sdk/ndk

* Added ARCore limited support for pose and rgb streams.

* Added AREngine support. Don't assert if depth size is not a modulo of rgb size.

* Added ARCore shared camera support

* android: fixed read/write runtime permissions for >=api23. arcore ndk: added feature point cloud. Fixed file sharing persmissions (>=api24 issue)

* ARCore NDK: mapping with feature point cloud

* android: Added post build strip command to reduce native library size

* android: fixed some compilation issues

* android: put back gtsam as default optimizer, manifest min api is dynamic based on cmake parameters

* AREngine: min api 24

* android: Fixed build without AREngine

* android: fixed not available libraries for API<24

* android: fixed build with old cmake versions

* android: set arcore min api to 23

* android: fixed arengine error on start when not built with native arengine support

* android: fixed tango camera permission for api>=23

* Added bionic android docker files

* Fixed wrong 3D words projection when depth size is not an exact multiple of rgb size. DbViewer: fixed images size not correctly shown in label of the calibration. ImageView: fixed depth scale when depth size is not a multiple of rgb size

* CameraMobile: added exact display rotation for local transform

* DbViewer: fixed gravity link shown in constraint view, show full local transform matrix in camera calibration label

* Android: fixed localization mode in visualization, fixed some tansitions between some UI states

* Android: Hide stop button when HUD is hidden. Updated About years.
2020-04-22 15:05:07 -04:00
matlabbe 931d525874 Fixed build on kinetic (octomap version issue #529) 2020-04-20 09:58:00 -04:00
matlabbe 7cfc51315d CMake: find octomap instead of OCTOMAP #529 2020-04-18 16:03:09 -04:00
matlabbe de4b17332d Preferences: fixed some not clickable external links 2020-04-17 16:06:56 -04:00
matlabbe 6074e84653 Fixed compilation issues with libtorch 1.4.0 2020-04-17 08:32:44 -04:00
matlabbe f575652456 0.19.7: added SuperPoint Torch feature support. RegVis: keep Feature2D detectors as class members instead of recreating them at each registration. 2020-04-16 17:59:45 -04:00
matlabbe 2ff582f06f DbViewer: fixed refineConstraints to make sure from id is the smallest id. Fixed correspondence lines drawn when images don't have the same size. 2020-04-15 14:54:36 -04:00
matlabbe de354b901d RegInfo: added icpStructuralDistribution info 2020-04-14 17:06:53 -04:00
matlabbe 607dc67135 IMU: removing yaw from local imu transform when creating gravity links 2020-04-10 19:24:45 -04:00
matlabbe d6269bb5d6 GUI: changed TF link colors from yellow to orange (as yellow already used for gravity) 2020-04-10 13:40:59 -04:00
matlabbe 43df2a05da OdomF2M: fixed roll/pitch ignored in imu local transform 2020-04-09 19:22:57 -04:00
matlabbe 1b4b1c2832 Report: add compilation when qt is not used 2020-04-09 11:00:42 -04:00
matlabbe 18ff5bb410 OdomF2M/Icp: fixed substracting points when normals are not used 2020-04-09 09:59:22 -04:00
matlabbe c0313a6d09 GUI/Source: color only option now also available for stereo cameras (meaning only left frame published). Db: fixed non-valid 3d words saved when no ones were in the signature (on loading, we don't set words3 if they are all null). 2020-04-08 20:00:41 -04:00
matlabbe 82a19a2ff1 DbViewer: Updated add constraint order (from=old, to=newer) 2020-04-08 18:52:38 -04:00
matlabbe 7e8e80db2c Fixed map_id not starting at 0 when empty 2020-04-08 17:02:44 -04:00
matlabbe cdff33b1c2 Added Mem/LocalizationDataSaved parameter 2020-04-05 19:21:20 -04:00
matlabbe e83838f744 CameraRealSense2: fixed ifstream imcomplete type error 2020-04-05 12:30:46 -04:00
matlabbe b3f7d1881f GUI: added options to hide map/odom frames and yellow TF links. CloudViewer: added option to show/hide camera axis 2020-04-03 20:04:15 -04:00
matlabbe 9c62a11316 fixed #525 2020-04-03 17:28:23 -04:00
matlabbe 034adb9f1f fixed #503 2020-04-02 15:07:32 -04:00
matlabbe fd1fa0320a fixed build with latest libpointmatcher 2020-04-01 15:52:46 -04:00
matlabbe b95195d8bb CameraRealSense2: added json preset file option (#513) 2020-04-01 12:25:28 -04:00
matlabbe dcc15f7555 MainWindow: added TG_error_lin and TG_error_ang stats for odometry (error of actual odometry transform compared to ground truth) 2020-03-31 11:52:27 -04:00
matlabbe 0eb978cb0b RegInfo: fixed copy without data. 2020-03-28 18:48:51 -04:00
matlabbe 451211cfb1 OdomInfo: added icpCorrespondences. Stats: using norm instead of x for distance/speed. Added odometry speed statistic in mph 2020-03-28 17:07:22 -04:00
matlabbe 06caa328a4 Lidar low complexity update. util3d::computeNormalsComplexity(): added optional transform (used in RegistrationIcp to get normal vectors in right coordinate frame). RegistrationIcp: Fixed PointToPoint ICP not used with PM when recomputing transform from low complexity. Added more info in warning messages when low complexity happens. OdometryF2M: avoid adding key frame when scan has low complexity. Same for the first frame to init the local scan map. 2020-03-28 16:25:27 -04:00
matlabbe 5122d9ac02 Memory: fixed fisheye distortion index error when rectifying only features 2020-03-24 11:46:16 -04:00
matlabbe d201e25006 CloudViewer: Fixed normals_scale=0 2020-03-12 16:41:52 -04:00
matlabbe b7bed0d1a5 Report: ignore total slam time on intermediate nodes 2020-03-12 14:12:00 -04:00
matlabbe 9993c4f2f7 Parameters.h: fixed warning C4305 2020-03-12 00:57:11 -04:00
matlabbe 5371f94c8f VS2019: fixed build 2020-03-11 23:34:55 -04:00
matlabbe 39724e239c rtabmap: fixed graph not re-optimized (if empty) after first localization on landmark 2020-03-10 13:08:47 -04:00
matlabbe bfc64c451a MainWindow: added /map and /odom coordinate frames 2020-03-10 10:30:42 -04:00
matlabbe 6133399b2e util3d: added intersectRayMesh() and intersectRayTriangle() functions 2020-03-03 14:32:12 -05:00
matlabbe c2dde973a6 Odometry: rectify stereo images for convenience if Rtabmap/ImagesAlreadyRectified is false and odometry strategy cannot process raw images 2020-03-02 16:57:14 -05:00
matlabbe 3ea64fbfc3 Rtabmap: do localization if a landmark already in graph is detected 2020-03-01 18:41:49 -05:00
matlabbe cb80d85dd6 DbViewer: removed graph optimization from latest optimized poses (see http://official-rtab-map-forum.67519.x6.nabble.com/Database-Post-Processing-Save-refined-links-td6504.html) 2020-03-01 16:59:46 -05:00
matlabbe dceec711e0 report: added --loop option to compute loop closure errors 2020-03-01 14:11:37 -05:00
matlabbe 67f1ce600f ament f7deefb31d for OpencV >=3.4.4 2020-02-29 15:22:14 -05:00
shovingtonandJohn d0f84f9460 add option to create a report.csv file in /tools/Report (#512)
Co-authored-by: John <john.bobzwik@gmail.com>
2020-02-27 16:28:02 -05:00
matlabbe 5daf4e5b2b Rtabmap: avoid optimizing for only gravity if odometry is already aligned with gravity 2020-02-26 13:40:03 -05:00
matlabbe 80bee99bfc ExportDialog: show (disabled) multi-band option even if not available for viewing (only for exporting) 2020-02-22 18:16:45 -05:00
matlabbe 882f2010ce MainWindow/rtabmapviz: Ignore Odometry stats included in rtabmap's Statistics object (to avoid plot reset when also receiving those from odom info) 2020-02-21 16:16:36 -05:00
matlabbe 352507cb1c Update downsampling filtering approach for ring-like lidars like the ouster 2020-02-21 15:01:31 -05:00
matlabbe e7a7ab8031 CloudViewer: added scan red colormap and max intensity options 2020-02-20 15:33:50 -05:00
matlabbe bd979cca34 Fixed rejected 180deg loop closure with multi-camera setup 2020-02-19 14:35:37 -05:00
matlabbe ab9f05fb0f Parameters: fixed "False" conversion independently of the case 2020-02-17 12:41:20 -05:00
matlabbe 5c197f176e DBViewer: fixed Yes vs YesToAll after editing 2d occupancy grid 2020-02-13 17:43:47 -05:00
matlabbe 5fef44ec2b DBViewer: Added option to crop empty space from local grid and scans after 2d occupancy grid is manually edited 2020-02-13 17:32:39 -05:00
matlabbe 79b480da4b Rtabmap: added addLink() function 2020-02-11 23:33:18 -05:00
matlabbe e1ecf55d03 fixed 14.04 build 2020-02-05 20:46:15 -05:00
matlabbe c9f21e7ebf fixed #498 2020-02-05 20:01:02 -05:00
matlabbe f7deefb31d Fixed compilation with OpenCV 4.2 #502 (see https://github.com/opencv/opencv/commit/ad146e5a6b931ac5d179d4fedc58cef99a3c9e7e and https://github.com/opencv/opencv/pull/16046) 2020-02-05 11:52:31 -05:00
matlabbe e2e2227895 ZED: Fixed compilation error with ZED SDK3 (#499). Added textureness confidence thr parameter (default 90, working only with ZED SDK3) 2020-02-03 17:59:07 -05:00
Walter Lucetti 8810c9e694 Compilation fixes (#501)
Great! Thx a lot!
It should fix issue #499 as well.
2020-01-31 14:17:10 -05:00
matlabbe f7540196d4 Fixed many compilation warnings (c++14, like pedantic warnings) 2020-01-30 17:23:02 -05:00
matlabbe ccc5a5be5a OctoMap::createCloud() added cloud probability output option.
CameraRealSense2: added new warnings to debug easier timestamps problems.
GUI: added gravity visualization.
DbViewer: empty clouds in OctoMap mode have color depending on probability of occupancy.
Brought general changes from local xvision branch.
2020-01-22 10:34:21 -05:00
matlabbe f9e818c900 CMake: alice vision option off by default (because it needs to be modified to be compatible https://gist.github.com/matlabbe/469bba5e7733ad6f2e3d7857b84f1f9e) 2020-01-06 13:39:35 -05:00
matlabbe 356094fac4 Intermediate nodes are now filtered if RGBD/LinearUpdate is set. 2019-12-20 17:07:31 -05:00
matlabbe 7d1a97696b OctoMap: fixed frontier with higher tree depth 2019-12-20 15:56:52 -05:00
Louis Petit af2b221958 OctoMap added frontier cloud output 2019-12-17 17:31:37 -05:00
matlabbe af9e113112 Gui: added missing OdomF2M/ScanRange parameter 2019-12-11 17:17:29 -05:00
matlabbe 62a2af193c fixed a compilation warning 2019-12-11 15:58:05 -05:00
PrescilliaA 4479a6f7e8 Odometry local map can be limited by range (#482)
* Odometry local map is now dependent on robot range and not on time, recalculating normals after adding new scan to the map as well
2019-12-11 13:43:38 -05:00
matlabbe 2d7ab7bdef Report: support Odometry/TimeEstimation/ms from ros 2019-12-11 11:33:19 -05:00
matlabbe 57a27a5d17 MainWindow: added virtual functions for convenience 2019-12-10 18:48:54 -05:00
matlabbe 1d7dee8976 kitti-tool: fixed no scan bug when using velodyne odom 2019-12-10 18:39:39 -05:00
matlabbe 9582ea4b55 Update .travis.yml 2019-11-24 09:57:49 -05:00
matlabbe edee5acdbf DBViewer: we can now add new links between disconnected maps using only lidar. Export: convert intensity to grayscale when exporting colored mesh. 2019-11-23 17:58:40 -05:00
matlabbe 85e7c9cf04 fixed undefined reference to vtkSmartVolumeMapper::SetRequestedRenderModeToRayCast() when using PCL 1.9.1 2019-11-21 04:07:38 +00:00
matlabbe b39fd0321e Update FindK4A.cmake 2019-11-19 09:39:42 -05:00
matlabbe 5f12459437 Docker removed disco and eoan images (keep only LTS images) 2019-11-09 08:48:55 -05:00
matlabbe 070b308595 Docker: xenial and bionic images now depend on ros:kinetic-perception and ros:melodic-perception respectively 2019-11-08 18:41:11 -05:00
matlabbe e7be12e0ff Docker: removed alicevision from xenial as Eigen >=3.3 is required 2019-11-06 09:58:52 -05:00
matlabbe d4cb623d9c docker: removed eol ubuntu distros 2019-11-04 08:46:58 -05:00
matlabbe 486b32a7d6 Added alicevision dependency in docker files. Added cosmic, disco and eoan docker files. 2019-11-03 21:14:47 -05:00
matlabbe 179f17d267 0.19.6: Added auto brightness/contrast and texture format options to multiband approach. rtabmap-export moved from examples to tools directory. 2019-11-03 14:10:02 -05:00
matlabbe 5d789f75a9 Merge branch 'alicevision' 2019-10-28 21:17:16 -04:00
matlabbe 2afa76c07c AliceVision integration, see util3d::multiBandTexturing() 2019-10-28 21:16:02 -04:00
matlabbe 260192bcc4 CameraRealSense2: Updated how D435i timestamp issue is handled (see also https://github.com/IntelRealSense/librealsense/issues/4505) 2019-10-25 18:21:40 -04:00
matlabbe c16b22de57 Added alicevision dependency 2019-10-24 08:56:23 -04:00
matlabbe 79ad8dc4be Fixed #453 2019-10-23 12:43:36 -04:00
matlabbe 6435c74bfe DBViewer: Added "Edit Constraint" button 2019-10-18 12:22:51 -04:00
matlabbe dd8e21e05d Features2D: set GFTT/ORB by default if GFTT/BRIEF is not available. RealSense2: fixed T265 local pose frame (when using realsense vio) 2019-10-13 19:04:11 -04:00
matlabbe 8924f9c5dc Docker/jfr2018: update msckf patch file (melodic) 2019-10-13 18:07:43 -04:00
matlabbe 981ac69c2c Zed-mini: added imu thread to publish async imu events at 200 Hz (to support VINS odometry). 2019-10-13 17:40:09 -04:00
matlabbe 1e298dcfa2 CameraRealSense2: updated how imu are published in inter mode and fixed some local transforms. GUI-VINS: features are shown in Odometry view. 2019-10-13 14:48:11 -04:00
matlabbe 9cb1e4bbc5 CameraRealSense2: Added Dual Mode (T265+D400) 2019-10-03 21:06:33 -04:00
matlabbe 3ab5ec218b Fixed #409 2019-10-01 20:53:48 -04:00
matlabbe d360420204 report tool: exporting poses in RGB-D dataset format by default, also exporting odom, slam and gt poses. 2019-09-29 19:38:54 -04:00
matlabbe 3fd5cdfb75 DbViewer/detect more loop closures: removed a messagebox when silent and icp-only is used 2019-09-26 12:29:11 -04:00
matlabbe 547da3f3ce CloudViewer: showing intensity as grayscale instead of generic color handler 2019-09-24 18:18:49 -04:00
matlabbe aeb2804da8 ViewClouds: fixed wrong color index used by default when normals are not computed with clouds having intensity 2019-09-24 15:55:25 -04:00
matlabbe cf1997804f ExportClouds: Fixed exported intensity values (packing/unpacking full float intensity value, not assuming 0-100 like before) 2019-09-24 15:46:35 -04:00
matlabbe ae374f134b Fixed https://github.com/introlab/rtabmap_ros/issues/351 2019-09-22 20:09:58 -04:00
matlabbe c437375f08 Localization: Fixed local map cleared when gravity links are added and no localization happened. Fixed "Word not found" error on initialization when Mem/InitWMWithAllNodes is true. 2019-09-19 15:23:18 -04:00
matlabbe 955660ba2a CameraRealSense2: added stereo ir support for D400 cameras, added publishInterIMU parameter (required for VINS fusion). 2019-09-18 20:55:48 -04:00
matlabbe b2b1977f8b Deprecated getClosestTransform(), use getTransform() instead. OdometryF2M: removed patch about forcing roll/pitch from IMU (BA is already doing the job). 2019-09-15 17:31:58 -04:00
matlabbe 350d3cd85f CameraRealSense2: fixed wrong IR image index. DBReader: fixed imu not published. OdometryF2M: use IMU roll/pitch values when IMU is used (reducing variance on those angles before BA). 2019-09-13 21:45:13 -04:00
matlabbe bdc8d839ff Optimizing the graph if gravity or prior constraints are added in SLAM mode 2019-09-12 18:56:01 -04:00
matlabbe 5b6eddabde Added support D435i IMU in IR mode 2019-09-12 17:21:35 -04:00
matlabbe e968fd3ef4 Remove landmark links when a node is deleted (and removed from the graph) #441 2019-09-01 13:17:44 -04:00
matlabbe 380fffb1d9 fixed #435 2019-08-27 15:30:13 -04:00
matlabbe 536f001479 Added OptimizerCeres class (Optimizer/Strategy=3) 2019-08-17 03:55:04 -04:00
matlabbe 38044040a6 Fixed mask when there are inf values in depth image 2019-08-16 16:38:25 -04:00
matlabbe 2a1b737470 OdometryVINS: fixed output pose orientation (D435i and euroc compatible) 2019-08-15 16:46:56 -04:00
matlabbe 4b118ae660 Added FastCV support (see FAST/CV parameter). VWDictionary: loading fixed dictionary only on updates (to avoid loading it multiple times when memory is reset). 2019-08-14 12:09:56 -04:00
matlabbe d5b4b25287 updated ORBExtractor opencv include (compatibility issue https://github.com/introlab/rtabmap_ros/issues/333) 2019-08-09 15:31:47 -04:00
matlabbe 262d74d1e3 fixed a compilation error 2019-08-01 16:29:44 -04:00
matlabbe 6767c2ade2 0.19.5: added Icp/RangeMin and Icp/RangeMax parameters 2019-08-01 16:21:01 -04:00
matlabbe 487caab349 CMake: added RTABMAP_QT_VERSION option (default auto) 2019-07-31 10:37:59 -04:00
matlabbe 283274e056 DbViewer: Added Gravity info (https://github.com/introlab/rtabmap_ros/issues/323) 2019-07-29 10:45:16 -04:00
matlabbe 1a5220182c CloudViewer: added vtkTexture.h include (#425) 2019-07-28 21:24:55 -04:00
matlabbe cd5e4f3055 Travis: added xenial build 2019-07-28 20:53:08 -04:00
matlabbe 7ea08b87d5 Travis: added bionic build 2019-07-28 20:46:04 -04:00
matlabbe a90356f0c9 fixed https://github.com/introlab/rtabmap_ros/issues/326 2019-07-26 14:03:32 -04:00
matlabbe 6713fe8bd2 fixed https://github.com/introlab/rtabmap_ros/issues/330 2019-07-25 13:15:44 -04:00
matlabbe 62d8a892c6 DbViewer: fixed graph not re-optimized after refining an added link. Rtabmap: RGBD/ProximityPathMaxNeighbors=1 means only nearest node on a path 2019-07-23 15:21:32 -04:00
matlabbe 3558640407 OptimizerGTSAM: fixed landmarks not transformed back in 3D after 2D optimization (slam2d) 2019-07-17 12:15:04 -04:00
matlabbe 5222506578 DbViewer: neighbor links can be rejected (a warning about splitting the graph is shown though) 2019-07-11 18:53:47 -04:00
matlabbe 89f1e809e6 CameraK4A: use mkv framerate if camera rate is -1. Preferences/Source: fixed imu filter parameters not reset on restore defaults 2019-07-11 18:13:20 -04:00
matlabbe 0973f48b2c CameraK4A: added finding lib on linux 2019-07-10 12:34:13 -04:00
matlabbe 3c7719f6d8 Added CameraK4A driver (only MKV playback supported yet). Fixed build with realsense2 support on Windows. Preferences: added imu filtering parameters to ini file. 2019-07-09 20:48:09 -04:00
matlabbe 63be7c85fc DBViewer: when adding new constraints, if visual reg is not used, we use optimized graph as guess 2019-07-05 16:28:31 -04:00
matlabbe 78d0d60b9f Added RealSense SR300 camera support (#421) 2019-07-05 11:19:45 -04:00
matlabbe bb94adc846 UPlot: Fixed backward compatibility with Qt4 2019-07-03 14:22:17 -04:00
matlabbe abbf7e4476 Updated UPlot data copy to include data of all curves (common x-axis), added also mean and max along stddev in legend item option 2019-07-03 12:01:34 -04:00
matlabbe 72e613fe28 UPlot: updated copy curve data to clipboard format to be more convenient for copy/paste directly in excel, also added curve names as header 2019-06-26 16:59:44 -04:00
matlabbe 49977b5475 Added ground truth localization error stats 2019-06-26 16:21:03 -04:00
matlabbe 9d8fd364e3 UI/Preferences: Adjusted Vis/MinInliersDistribution decimals 2019-06-18 14:22:29 -04:00
matlabbe 50fdc210c9 Memory: added some warnings about pre-postdecimation parameters, updated their description (removed negative decimation comment) 2019-06-17 10:19:54 -04:00
matlabbe d205683eb5 Added parameters Vis/MeanInliersDistance and Vis/MinInliersDistribution 2019-06-16 18:54:39 -04:00
matlabbe 85edc57ba5 Added RGBD/MaxLocalizationDistance parameter 2019-06-12 16:03:52 -04:00
matlabbe b5f5623af4 CameraRealSense2: updated how stamping is done, updated default D435 frame resolution/fps 2019-06-06 17:17:11 -04:00
matlabbe e09a872fa2 GUI: added word wrap to transform label in loop closure viewer. Memory: creating a RegistraitonVis for stereo from motion if memory's registration pipeline is not vis only. 2019-06-02 14:59:11 -04:00
matlabbe cdbdc36c94 RegICP: Updated warning when complexity is too low. LoopClosureViewer: fixed scan transform. 2019-06-02 12:38:09 -04:00
matlabbe 8cb923b332 Reduced local bundle on loop closure iterations to 5. Updated graph::filterLinks() to handle selfRef link type. DbViewer: removed gravity constraints from constraints view. 2019-06-01 21:43:13 -04:00
matlabbe ec943198f0 Rtabmap: re-optimize at each frame when gravity constraints are added 2019-05-31 19:31:11 -04:00
matlabbe 4c8af6d6e9 fix build errors with opencv2, added Transform::getClosestTransform() function for convenience. 2019-05-31 16:51:37 -04:00
matlabbe d5d00fbd7d merged master to imu_feature 2019-05-31 15:39:49 -04:00
matlabbe e887d462ce Memory: Added parameter Mem/UseOdomGravity, adding kGravity links when creating a node if IMU is present or Mem/UseOdomGravity is set. Fixed OpenCV4 related build errors on stereo fisheye rectification code. Signature: changed links from map to multimap to support having multiple self references (prior, gravity constraints...). DBReader: publish IMU orientation if a gravity link is detected. 2019-05-31 15:36:35 -04:00
matlabbe cd6e51a968 fixed #401 2019-05-30 10:04:40 -04:00
matlabbe 71f7515775 Added resolution parameters for Usb camera and realsense2 sources 2019-05-15 19:21:32 -04:00
matlabbe f8a8e55e7e UI: Update preferences with the new imu filter parameters. Camera: added imu filtering option. Updated support for zedm, D435i and T265. 2019-05-13 18:42:46 -04:00
matlabbe cbca362cc4 Added T265 odometry support 2019-05-12 19:27:32 -04:00
matlabbe 750ad5bd44 Fixed build error without realsense2 2019-05-11 16:11:19 -04:00
matlabbe e03a9b3003 DBViewer: fixed Optimizer/GravitySigma not used on optimization 2019-05-10 11:45:15 -04:00
matlabbe d4b4379829 Added T265 support (stereo-only yet) 2019-05-09 19:20:26 -04:00
matlabbe 5b5b594f4a Fixed assert when Mem/DepthAsMash=false and Vis/MaxDepth or Vis/MinDepth are set 2019-05-07 21:09:46 -04:00
matlabbe e6f471d88e Added imu to odom bundle adjustment. Added IMUFilter classes. Changed Aruco parameter prefix to Marker. Zed: publishing IMU data. 2019-05-07 18:57:53 -04:00
matlabbe 0fd69f22d4 fixed a comment typo 2019-05-04 15:03:09 -04:00
matlabbe cc95ca1cf6 Fixed dim assert with binary descriptors and fixed dictionary 2019-05-04 14:58:02 -04:00
matlabbe 4675240d6e Tango: added setCanceledOnTouchOutside() on all dialogs 2019-04-29 18:08:16 -04:00
matlabbe 630b565cd4 reprocess: added double dash support for arguments for convenience. Rtabmap: fixed typo in localization verification by odom graph optimization. 2019-04-29 17:11:29 -04:00
matlabbe 125d532e95 Added graph::calcRelativeErrors() and option --relative for report. Added skip frames option on rgbd_dataset tool. 2019-04-27 20:39:40 -04:00
matlabbe 195f6147ad DBViewer: added feature/line color menu option. CameraImages/DBReader: added maxFrames parameter 2019-04-26 19:20:35 -04:00
matlabbe cd2c261e2b EditDepthArea: added cluster error menu option, fixed seg fault on large cluster removal 2019-04-26 18:03:07 -04:00
matlabbe 38a83c0cd9 DbViewer: disabling all buttons in Constraints View when visualizing a landmark link 2019-04-26 14:14:35 -04:00
matlabbe a5350c4891 Optimizer: fixed bad g2o optimizations on 2d slam when there are 3D landmarks (#384). DBViewer: landmarks can be now visualized. 2019-04-26 14:03:25 -04:00
matlabbe f9b7b54454 Dictionary: new bin descriptor to 32f conversion. RegVis: removed octave comparisons. 2019-04-24 01:24:55 -04:00
matlabbe 1a71406f84 Fixed Windows build (std::back_inserter not found) 2019-04-23 16:15:50 -04:00
matlabbe f1ae4002aa 💄 run_euroc_datasets.sh 2019-04-23 09:07:15 -04:00
matlabbe d4585960fc RegVis: fixed orboctree descriptor extractions. KeypointItem: fixed placeholder gray scale for yellow features. 2019-04-22 19:50:41 -04:00
matlabbe 191de5baea docker/jfr2018: fixed kitti run script 2019-04-21 19:34:40 -04:00
matlabbe ef2c68d768 Fixed build with opencv2 2019-04-18 20:37:50 -04:00
matlabbe a0f74eaee2 Added new 2d feature ORB OcTree (approach used in ORB_SLAM2). report tool: fixed assert caused by bidirectional links. detectModeLoopClosures tool: check if input path exists. 2019-04-18 19:50:58 -04:00
matlabbe 8a6c0dad00 Fixed build with Qt4 2019-04-17 19:36:15 -04:00
matlabbe bc2f89e66f DbViewer: added a progress dialog when loading a database 2019-04-17 16:46:03 -04:00
matlabbe 23602935e1 Optimizer::getConnectedGraph() fixed poses created by propagating links (more robust to multi-session) 2019-04-17 15:30:47 -04:00
matlabbe aaefdae794 DBViewer: improved loading time on large dbs 2019-04-17 14:57:56 -04:00
matlabbe 38cdc76790 reprocess: added more localization info 2019-04-17 14:57:15 -04:00
matlabbe a668ec35ab Export: normal estimation can be disabled, clouds can be exported with normals 2019-04-17 13:45:42 -04:00
matlabbe 7acaac7a6d g2o: fixed vertigo index when using landmarks. graphViewer: fixed outlier wrong set to some landmark links 2019-04-12 21:31:20 -04:00
matlabbe 428d5be129 fixed compilation warning 2019-04-12 19:27:12 -04:00
TouchDeeper 2de553ba02 fix the realsense release problem (#381)
Great! thx!
2019-04-12 18:26:36 -04:00
matlabbe 77ae8e108a 0.19.2: Refactored SensorData interface. DBReader: Fixed GPS not published. #345: both g2o and gtsam working with GPS. g2o: added gravity edges. 2019-04-09 20:05:24 -04:00
matlabbe e7b3a7735d Parameters.cpp: fixed build without VTK 2019-04-05 20:51:57 -04:00
matlabbe 9b63297a6b New parameter "RGBD/MaxOdomCacheSize" used in localization mode to reject similar locations (default disabled) 2019-04-05 19:37:40 -04:00
matlabbe ae12caff04 rtabmap: Adjust transforms with gravity on localization mode if Optimizer/GravitySigma is not null 2019-04-05 16:58:57 -04:00
matlabbe 61098be315 Update .appveyor.yml 2019-04-03 20:21:21 -04:00
matlabbe 727e4fe672 Updated --version info 2019-04-02 14:07:54 -04:00
matlabbe fc9c762516 Added Optimizer/GravitySigma parameter (with GTSAM support). 2019-03-31 15:51:50 -04:00
matlabbe 35933cafba Rtabmap::setInitialPose() update optimized poses if empty 2019-03-27 22:07:06 -04:00
matlabbe 09ced82c9f Rtabmap::triggerNewMap() now does nothing in localization mode to make sure optimized map doesn't get regenerated 2019-03-27 20:48:00 -04:00
matlabbe 81313c32ee detectMoreLoopClosures tool: Fixed windows build 2019-03-27 16:12:49 -04:00
matlabbe 8c92ed25e5 Rtabmap::detectMoreLoopClosures(): publish more progression messages for every loop closure found. rtabmap-detectMoreLoopClosures: we can do ctrl-c to interrupt the processing safely. 2019-03-27 15:39:46 -04:00
matlabbe 80ef0e1a75 DbViewer: improved opening time of large databases when info tab is not visible 2019-03-25 16:30:03 -04:00
matlabbe 73e15ee93d DBViewer: Fixed message box text error when a constraint is rejected by too large angle 2019-03-25 16:09:09 -04:00
matlabbe 7cd7ce3b41 Odom/GuessSmoothingDelay changed default to 0 (tum long_office_household rosbag orientation issue on the teddybear) 2019-03-21 11:49:44 -04:00
matlabbe 6f4dce52fc OdometryOkvis: return pose only after processing measurements (images) 2019-03-20 22:10:15 -04:00
matlabbe ae3d651e83 updated run_tum_datasets.sh 2019-03-20 19:44:40 -04:00
matlabbe 0f552b4b65 Update run_kitti_datasets.sh 2019-03-20 19:39:33 -04:00
matlabbe 7a52f316f9 Update README.md 2019-03-20 19:38:23 -04:00
matlabbe 3cafdf911b Docker: added new "latest" version of jfr2018 image (including VINS and latest rtabmap version). Updated jfr2018 scripts to easily switch to host installed rtabmap instead of docker 2019-03-20 19:36:56 -04:00
matlabbe 24a4d91ee8 OdometryOKVIS: added warning if config file doesn't exist, also replace ~ by home directory for convenience 2019-03-20 13:10:14 -04:00
matlabbe b2fe138dbf OKVIS: force ceres 1.9.0 version 2019-03-20 12:58:06 -04:00
matlabbe e8e3649f24 Grid/OctoMap: updated update() interface to return boolean to know if the map has been updated 2019-03-19 14:10:30 -04:00
matlabbe c0a7c3a344 0.19.1: Added OdometryVINS (VINS-Fusion integration, Odom/Strategy=9) 2019-03-18 20:45:34 -04:00
matlabbe 9c1c88d35e Tango: added marker's max depth error setting 2019-03-18 10:37:02 -04:00
matlabbe c44349511d Fixed build with opencv < 3 2019-03-17 13:02:04 -04:00
matlabbe 0c8194373f DbViewer: added "Edit optimized map" and "Regenerate Optimized Map" actions 2019-03-16 15:27:49 -04:00
matlabbe c8db45b2a4 reverted 977f8eb262 (was not the problem...) 2019-03-14 19:06:32 -04:00
matlabbe a0a566140c rtabmap::computePath(pose) fixed fatal error when landmarks are in the graph 2019-03-14 17:16:51 -04:00
matlabbe 977f8eb262 OdometryF2M: fixed orientation ignored when setting initial pose for scans 2019-03-14 14:15:53 -04:00
matlabbe 8edd85a9df Tools: don't build rgbdcamera tool if rtabmap_gui is not built 2019-03-13 11:32:42 -04:00
matlabbe f1f0c39be8 Fixed localization done in 3d instead of 2d when Reg/Force3DoF was true 2019-03-08 17:31:05 -05:00
matlabbe cf4db63226 New parameter: OdomF2M/ValidDepthRatio 2019-03-06 12:35:54 -05:00
matlabbe d85c1c3bcf DbViewer: EditDepth colormap now matches the one in main window 2019-03-05 10:48:05 -05:00
matlabbe 884d1d7684 DbViewer: added colormap menu option to EditDepthArea, update3dView() updates only last select id to avoid switching to second image after editing the depth of the first one. 2019-03-05 10:07:20 -05:00
matlabbe 45fa968076 fixed EdgeSE3XYZPrior not defined build error when using latest g2o version (#360 #363) 2019-03-03 15:27:32 -05:00
matlabbe 530da08145 Added Aruco/MaxDepthError parameter 2019-03-01 18:34:49 -05:00
matlabbe c272f9538a Rtabmap/StartNewMapOnGoodSignature: start mapping if landmark is also detected. Rtabmap::detectMoreLoopClosures(): Fixed crash when landmarks are in optimized poses. 2019-02-28 20:33:16 -05:00
matlabbe 0ee4d6084b Increased minor version to 0.19 (Tag table not existing anymore) 2019-02-27 14:01:55 -05:00
matlabbe ebf74e3c98 DbViewer: removed debugging warnings 2019-02-25 09:48:18 -05:00
matlabbe e1290524af DbViewer: fixed proximity scans not shown 2019-02-23 19:16:12 -05:00
matlabbe 06ba3cfd73 docker: updated introlab3it/rtabmap:android-deps image with OpenCV 3.4.2 2019-02-23 18:14:15 -05:00
matlabbe 222db70cf6 Tango: Added AprilTag dictionaries for marker detection option. 2019-02-23 23:11:24 +00:00
matlabbe eef47e1681 Aruco/MarkerLength: set default to 0 for convenience (auto estimation). 2019-02-22 22:07:07 -05:00
matlabbe 17521e8efb Tango: added "Settings->Mapping->ArUco Marker Detection" option 2019-02-23 03:02:42 +00:00
matlabbe d089e95e5a MarkerDetection: added automatic marker's length estimation when depth image is provided (and when Aruco/MarkerLength is 0). 2019-02-22 20:01:09 -05:00
matlabbe e635f35cf1 Fixed build for OpenCV 3.1.0 2019-02-22 21:55:25 +00:00
matlabbe 5f54bd13bb Fixed build with OpenCV 3.2.0 (including opencv_contrib) 2019-02-22 15:27:25 -05:00
matlabbe f27da7c8a5 GUI: fixed seg fault when showing scan with intensity and computed normals 2019-02-21 17:51:07 -05:00
matlabbe 49a41d7e46 util3d::downsample() added intensity type support 2019-02-20 17:53:53 -05:00
matlabbe 2863060ded fixed a logging error 2019-02-18 19:07:27 -05:00
matlabbe 75025895b8 Fixed build with OpenCV's aruco module 2019-02-18 19:02:53 -05:00
matlabbe d6ca37a9e7 Integration of OpenCV's ArUco Marker Detection (see new parameter "RGBD/MarkerDetection") 2019-02-18 18:19:55 -05:00
matlabbe 08f3e6c08e RGBD/LocalBundleOnLoopClosure: disabled on neighbor refining and fixed Reg/Force3DoF ignored 2019-02-17 21:57:52 -05:00
matlabbe dd5e09be37 DbViewer: fixed fatal error when adding new constraints on nodes not in the graph (now we can only add new constraints with nodes in the graph) 2019-02-15 17:43:18 -05:00
matlabbe caf165a635 CameraModel: Fixed fisheye distortion params copy 2019-02-15 16:55:57 -05:00
matlabbe 15ca0da89e Fixed Tango build 2019-02-12 16:48:37 -05:00
matlabbe 3e71b3fe69 OctoMap: aligned 2D projection map with OctoMap 2019-02-12 15:36:28 -05:00
matlabbe 5839ccbeb5 OccupancyGrid: fixed some obstacles not added when Grid/RayTracing and Grid/3D are true 2019-02-12 15:35:33 -05:00
matlabbe 38b8746507 Added Mem/ImageCompressionFormat parameter (default .jpg) 2019-02-11 15:23:38 -05:00
matlabbe 99944b1d49 Added FLANN_KDTREE_MEM_OPT cmake option 2019-02-07 20:52:20 -05:00
matlabbe 1752b55678 Fixed bug with proximity detection (with combined scans) giving wrong transform sometimes if RGBD/ProximityPathFilteringRadius was used (default true). Fixed util3d::computeNormalsComplexity() when scan has intensity. 2019-02-07 11:19:55 -05:00
matlabbe 6fc884b575 Export: exporting with intensity for laser scans 2019-02-06 18:46:37 -05:00
matlabbe c8cd745f81 Rtabmap: On init, load also landmark optimzed poses 2019-02-04 18:23:09 -05:00
matlabbe c85ff90477 fixed build with older gtsam versions 2019-01-29 19:06:28 -05:00
matlabbe 0c24786912 Fixed build with latest gtsam version (missing DerivedValue.h, https://github.com/introlab/rtabmap_ros/issues/290) 2019-01-29 18:06:38 -05:00
matlabbe d647fd7743 Fixed regression build error with OpenCV2 2019-01-28 19:56:11 -05:00
matlabbe 5eb9bbe283 GUI: Fixed black zed depth image in ImageView (#356) 2019-01-28 19:47:01 -05:00
matlabbe f8b7421b59 Fixed build with OpenCV4+CUDA10 (#334) 2019-01-28 19:28:24 -05:00
matlabbe 76ef2c4b0e CameraStereoZed: added odomForce3DoF option 2019-01-28 17:05:15 -05:00
matlabbe 0192cac18a updated recovery tool to support databases without image data kept 2019-01-28 16:11:05 -05:00
matlabbe ccaf15fc41 fixed build without g2o 2019-01-25 19:14:28 -05:00
matlabbe f50018776f Fixed Icp/CorrespondenceRatio not updated if set in parameters for proximity detection 2019-01-21 16:55:38 -05:00
matlabbe c13267599e MainWindow: Re-added rotation of the map on the graph view based on gps, if used and if priors are ignored by optimizer 2019-01-16 20:25:14 -05:00
matlabbe d45b77c0b7 Vis: fixed assert when doing bundle adjustment with SignatureTo having no 3d words 2019-01-16 19:29:57 -05:00
matlabbe 479fb6cbca rtabmap: update lastLocalizationNodeId even when only a landmark is detected 2019-01-15 21:34:01 -05:00
matlabbe 95f48b694e OptimizerGTSAM: fixed inverted landmark link transform on slam2d with rotation used 2019-01-15 17:58:23 -05:00
matlabbe 9da2c1918f CameraImages: moved scan filtering stuff to CameraThread
Preferences->Source: refactored scan filtering parameters
OdometryF2M and OdometryF2F: moved odom orientation init from IMU to OdometryROS instead
2019-01-15 15:41:07 -05:00
matlabbe 42c8ed0c0f removed a debug warning 2019-01-09 13:52:53 -05:00
matlabbe d63f9e736e gui: fixed odom local map hiding on rtabmap update 2019-01-09 13:50:12 -05:00
matlabbe 2a8e5be361 g2o: only check for variance >= 9999 as zero should never happen. For landmark, use SE3 or PointXYZ factor depending if angular covariance is set or not (>=9999). Same for gtsam (pose vs bearingRange factor respectively). 2019-01-06 17:00:39 -05:00
Nuno Marques bf5d2b7f04 EdgeSE3XYZPrior: add ParamOffset (#349) 2019-01-04 12:45:30 -05:00
matlabbe 18c35954f0 g2o: fixed indigo build errors 2019-01-03 16:16:16 -05:00
matlabbe 36d7e58ff2 Merge branch 'TSC21-pr-add_edge_xyz_priors_for_gps' 2019-01-03 15:50:14 -05:00
matlabbe 0f8c70bcdf g2o/gps support: added edge_se3_xyzprior.h to rtabmap repo. Fixed build for kinetic g2o version. 2019-01-03 15:49:25 -05:00
matlabbe 248d6f1167 Merge branch 'pr-add_edge_xyz_priors_for_gps' of https://github.com/TSC21/rtabmap into TSC21-pr-add_edge_xyz_priors_for_gps 2019-01-03 14:10:20 -05:00
matlabbe 35974d55bd updated jfr2018 docker image (made it standalone, depending only on ubuntu:16.04 image) 2018-12-30 15:43:14 -05:00
matlabbe 5548f33e06 Update README.md 2018-12-29 17:17:46 -05:00
matlabbe a909461535 Added jfr2018 docker image to reproduce kitti/euroc/tum results from the corresponding paper 2018-12-29 17:15:36 -05:00
TSC21 698293e2d8 OptimizedG2O: assotiate VertexSE3 instead of VertexPointXYZ to EdgeXYZPrior 2018-12-28 14:10:00 +00:00
TSC21 22d631d7aa OptimizerG2O: fix landmarks vertex output types 2018-12-28 14:08:05 +00:00
TSC21 be75c7591c OptimizerG2O: fix slam2d prior types naming 2018-12-28 13:38:12 +00:00
TSC21 c21f466573 OptimizerG2O: fix EDGE_XYZ / XY_PRIOR exports 2018-12-27 17:08:54 +00:00
TSC21 308b1484e0 OptimizerG2O: check inverse of the information matrix values 2018-12-27 15:58:25 +00:00
TSC21 8beea1984e Memory: pass globalPoseCovariance without inverting it 2018-12-27 15:06:29 +00:00
TSC21 cebecc3fc3 OptimizerG2O: add EDGE_XY_PRIOR and EDGE_XYZ_PRIOR to saveGraph 2018-12-27 13:22:15 +00:00
TSC21 81c4382349 OptimizerG2O: improve priors SE3/SE2 vs XYZ/XY logic 2018-12-27 12:48:24 +00:00
TSC21 b7f2eb8df9 OptimizerG2O: add XYZ/SE3 and XY/SE2 priors depending on the angular covariances 2018-12-26 16:30:40 +00:00
TSC21 97f956f138 Memory: readd GPS data as priors 2018-12-26 15:37:22 +00:00
matlabbe 6bd9dd55b7 3D view, fixed flickering frustum 2018-12-13 18:00:19 -05:00
matlabbe 6e8913091d ImageView: fixed image not saved if extension not set (set default png) 2018-12-13 17:54:46 -05:00
matlabbe 85f0ab829a Rtabmap: updated logic of small displacement updates (RGBD/LinearUpdate=0 means always update) 2018-12-13 13:30:50 -05:00
matlabbe 73004c643c DbViewer: In graph view, nodes in latest working memory state are highlighted in red 2018-12-13 13:24:57 -05:00
matlabbe ccbc802fe6 Fixed angular error check when abs angle error > PI 2018-12-10 20:20:52 -05:00
matlabbe 73378c4d56 fixed compilation warning 2018-12-09 14:16:51 -05:00
matlabbe 986db04cb9 Rtabmap::computePath() make sure the closest pose of the current location is a node, not a landmark 2018-12-07 20:43:46 -05:00
matlabbe de32e53868 OctoMap: fixed not dense empty cells 2018-12-07 19:50:15 -05:00
matlabbe 200ec8e5db 0.18.3: added landmarks (graph optimization, localization, navigation) 2018-12-07 18:29:41 -05:00
matlabbe b771aa00e0 LaserScan: Updated max points computation 2018-12-04 10:17:21 -05:00
matlabbe 26b33b12af Updated -march=native warnings with latest PCL version 2018-12-02 13:54:17 -05:00
matlabbe f0ea8ab076 OdometryThread: fixed data buffer ignored if imu is always set 2018-12-01 00:53:36 -05:00
matlabbe abbcc4f8a9 CameraFreenect: set accelerometer values in IMU member of SensorData. OdomF2M and OdomF2F: intialize orientation with gravity for the first frame if accelerometer value is valid in SensorData. 2018-12-01 00:25:48 -05:00
matlabbe 8a8f46c325 fixed #341 2018-11-29 18:21:12 -05:00
matlabbe d2813ed70b fixed vtkGUISupportQt linker errors on RPI3 2018-11-28 14:10:29 -05:00
matlabbe 0167687c6b Link: Covariances are added on merge when output is NeighborMerged (reduced graph) 2018-11-27 09:23:16 -05:00
matlabbe ca27dbd2fe Fixed #339 and #289 2018-11-21 14:47:15 -05:00
matlabbe b862d6bc48 0.18.2: Added Odom/GuessSmoothingDelay parameter 2018-11-21 11:57:04 -05:00
matlabbe 5ae2f487b4 Odom: Updated error msg when invalid stamps are received 2018-11-19 18:19:24 -05:00
matlabbe 283c1df00c Fixed labels not correctly shown. Fixed planner not sending next goals when memory management is disabled. 2018-11-19 18:00:24 -05:00
matlabbe bf2a9db5e4 Fixed memory usage for grid and statistics 2018-11-15 20:52:53 -05:00
matlabbe 963aea5c0d OccupancyGrid:segmentCloud() reset indices ptr to make sure the returned pointer is valid 2018-11-15 10:08:04 -05:00
matlabbe 9efd7c14fc Updated stereo block matching approach (when Stereo/OpticalFlow=false) 2018-11-13 14:25:21 -05:00
matlabbe 227f8c4f86 Camera: fixed freezing when changing online frame rate from non zero to zero 2018-11-10 11:43:58 -05:00
matlabbe be498b4cb7 bump 0.18.1 version 2018-11-09 21:01:05 -05:00
matlabbe 015c442f1c DetectMoreLoopClosures: update optimized poses and clear occupancy grid saved in database 2018-11-09 20:36:58 -05:00
matlabbe be1532b809 Updated wifi example 2018-11-09 18:09:12 -05:00
matlabbe 8333677dc6 Improved/optimized Rtabmap timing performance for large datasets 2018-11-09 17:28:55 -05:00
matlabbe 3bb874825f Optimizer:getConnectedGraph() don't add poses not included in the input poses 2018-11-09 17:14:09 -05:00
matlabbe c43bd6cd3f Fixed backward compatibility error with libpointmatcher < 1.3.0 2018-11-09 16:06:44 -05:00
matlabbe 5159171bf3 Fixed build with latest libpointmatcher version 2018-11-09 10:12:30 -05:00
matlabbe c5057eb6b3 exportGraph: added RGBD-SLAM format (10) without motion capture coordinate transformation (#332) 2018-11-08 12:26:37 -05:00
matlabbe 433e20869c fixed #333 2018-11-08 10:52:12 -05:00
matlabbe 0c4a91df8a New tool: rtabmap-detectMoreLoopClosures 2018-11-06 17:19:16 -05:00
matlabbe 71ae076b44 BayesFilter: improved performance when prediction didn't change or only a new id is appended to prediction. Memory: fixed seg fault when using local bundle adjustment on loop closure and memory management is enabled. 2018-11-06 14:45:57 -05:00
matlabbe 1784a0877f PostProcessingDialog: don't close dialog if validate failed 2018-11-05 18:49:50 -05:00
matlabbe 09a63bbc5b Rtabmap::detectorMoreLoopClosures() added intraSession and interSession parameters 2018-11-05 18:40:08 -05:00
matlabbe 4f1deef971 Proximity detection by space: sort nearest paths by likelihood values 2018-11-05 14:24:04 -05:00
matlabbe c2b1a9fbd7 Fixed long loading time of large working memory 2018-11-05 11:50:49 -05:00
matlabbe 9d62d04459 Update README.md 2018-11-02 13:29:11 -04:00
matlabbe d02bb9af5d Update .appveyor.yml 2018-11-02 13:28:30 -04:00
matlabbe f670f71d47 Updated appveyor with yaml-cpp dependency 2018-11-02 12:45:57 -04:00
matlabbe b96bc2a240 Detecting OPENCV_ENABLE_NONFREE if set on OpenCV>=3.4.3 2018-11-02 11:52:35 -04:00
matlabbe 8eda6cbdf0 Update .appveyor.yml 2018-11-01 19:26:04 -04:00
matlabbe f05eefd80c CMake: fixed MSVC detection for /MP 2018-11-01 18:07:52 -04:00
matlabbe 4bfa1c2752 Windows: Added /MP for parallel compilation with MSVC 2018-11-01 17:49:18 -04:00
Mathieu Labbé 961549d375 Updated CameraStereoFlyCapture2 with triclops new API 2018-11-01 17:17:38 -04:00
matlabbe 4e3e5872fc Update .appveyor.yml 2018-11-01 11:25:11 -04:00
matlabbe de7ceb91dd Windows packaging: adding missing qwindowsvistastyle.dll to get windows Vista/7/10 native look 2018-11-01 10:38:09 -04:00
matlabbe d62dcdd29a Updated appveyor with more dependencies, updated zed find package on Windows, updated FindFlyCapture2.cmake 2018-10-31 20:56:34 -04:00
matlabbe 8087774961 Added contributor to CameraStereoTara files 2018-10-31 11:05:06 -04:00
matlabbe fad1993a01 Preferences->Source: added Tara stack widget panel 2018-10-31 11:00:01 -04:00
e-con Systems India Pvt Ltd 53513b6632 Tara Camera added to Master branch (#331)
* Tara Camera integration

* Update preferencesDialog.ui

* Update preferencesDialog.ui
2018-11-01 02:57:07 +12:00
matlabbe bb4164a05d CloudViewer: added some getters 2018-10-30 17:42:43 -04:00
matlabbe 69f3116158 Updated reprocess 2018-10-30 10:40:35 -04:00
matlabbe e57b722ce2 Reprocess: if Mem/IncrementalMemory is false and more than one input file is provided, init rtabmap with the first and do localization with the others. 2018-10-29 17:00:42 -04:00
matlabbe a43eccdac8 MainWindow: clear cacheLocalizationsCount when unchecking the option 2018-10-25 19:08:00 -04:00
matlabbe 12a7349165 Removed Optimizer:computeBACorrespondences() duplicated 3d points (more than 2 frames can reference a 3D point), added option to rematch features. Bundler: added more options to export dialog, fixed inverted colors. 2018-10-25 16:31:13 -04:00
matlabbe 1ef61db73b Bundler: fixed 3D points orientation, added color. 2018-10-24 20:34:53 -04:00
matlabbe c14e20330f Fixed SIFT octave issue causing registration to always fail. Added Bundler export points option. 2018-10-24 20:01:57 -04:00
matlabbe 299bec15ff DBReader: publish global pose if prior link is detected, negative image rate means now a ratio of the database stamps 2018-10-24 09:26:41 +12:00
matlabbe 8e99291e13 0.18: Camera calibration and LaserScan Info refactoring (#324)
* Saving full camera calibration in database, added angle min/max/inc to LaserScan.

* Updated laserscan info save/load in db

* Database: added Tag table, added env_sensors field to Node

* fixed serialization/deserialization of stereo camera model

* fixed multi-calibration db saving

* fixed rebase errors

* Tango: Added saving environmental sensors option

* Memory: Save env sensors

* Tango: fixed env sensor ids

* DBViewer: show env sensors values

* DBViewer: added calibration details on tooltip

* increased package version to 0.18.0

* Fixed LaserScan copies when angleIncrement is valid

* fixed build error without OctoMap dependency
2018-10-23 14:35:14 -04:00
matlabbe 8701ae6de0 Update OptimizerG2O.cpp
#323
2018-10-24 06:18:10 +12:00
matlabbe d2c406f019 fixed build without g2o (#323) 2018-10-24 06:16:40 +12:00
matlabbe d2abc3a237 Added parameter Rtabmap/LoopGPS (default true) to enabled/disable the use of GPS in likelihood computation 2018-10-22 14:39:30 -04:00
matlabbe 3bc8fc4c11 Integrated GPS into likelihood computation 2018-10-22 12:31:07 -04:00
matlabbe 93a3a667c8 fixed build errors with OpenCV2 caused by commit https://github.com/introlab/rtabmap/commit/39e1d453697b7cdd9dd11038f6d9d998b8a8ed53 (OpenCV4) 2018-10-21 13:53:49 -04:00
matlabbe 39e1d45369 Fixed build with OpenCV4 (#322) 2018-10-21 13:35:03 -04:00
matlabbe cc91208057 Tango: fixed wrong bearing value on landscape orientation 2018-10-18 18:23:52 -04:00
matlabbe 5d54c0e26c Tango: updated copyright years 2018-10-18 17:25:57 +00:00
matlabbe 5fc9f859ce Tango: set third person camera by default, scan media file on SD-card when saving database (fixed issue of database just saved not seen with MTP when connected by USB) 2018-10-17 14:05:22 -04:00
matlabbe 4c7b565391 Refactored Optimizer::getConnectedGraph() to estimate poses based on links, we can then remove Optimizer::optimizeMultiSession(). Rtabmap: if poses and guess are not the same before optimization, do Optimizer::getConnectedGraph() to get pose estimates based on links instead of odom (to make optimization more robust to memory management and multi-session). 2018-10-16 18:55:36 -04:00
matlabbe f1546c1fca Replaced all optimizeIncremental() by optimizeMultiSession() to fix GTSAM errors when merging multiple maps together. DBReader: always publish saved stamp. DBViewer: added actions to set covariance of all neighbor or loop closure links. 2018-10-15 17:07:18 -04:00
matlabbe b2c012d8bc Updated g2o and toro saveGraph() to use Optimizer's parameters (#320, #319) 2018-10-15 13:41:44 -04:00
Nuno Marques 42c60c7154 OptmizerG2O: add prior edge export (#319)
* OptmizerG2O: add prior edge export

* add required conditions and structure to export prior edges

* for now, make the graph exportation of priors not dependent of parameters

* include <locale.h> so to use setlocale() in a windows build
2018-10-15 11:58:57 -04:00
matlabbe 444b511548 rtabmap: use last argument with db suffix as the database used (fixed issue when setting a dictionary path as argument) 2018-10-15 11:33:46 -04:00
matlabbe 527cbddb4b rtabmap app: default log level is now warning. This avoids showing log stuff when using --params argument for example. 2018-10-12 16:03:29 -04:00
matlabbe 7fdd212462 rtabmap-reprocess supports multiple input databases. Arguments "--params map.db" output parameters of the database in INI format 2018-10-12 15:53:44 -04:00
matlabbe 9f31830f03 Install system libraries only in BUILD_AS_BUNDLE mode, install vcomp###.dll is built with openmp 2018-10-11 15:19:20 -04:00
matlabbe e4098cb54b Fixed GTSAM search by ignoring findGTSAM.cmake file from PCL 2018-10-11 14:28:41 -04:00
matlabbe aa13ea1a80 Update .appveyor.yml
Added GTSAM_DIR variable to cmake to help finding GTSAM, Using OpenCV2 instead of OpenCV3 binaries as BRIEF is not available in OpenCV3 binaries.
2018-10-09 20:46:58 -04:00
matlabbe b717910db8 Fixed QMutex still locked on exit warning. Removing old parameters from ini file on saving. Memory: Removed completely the use of Vis/CorType (only used by F2F odom). 2018-10-04 17:09:03 -04:00
matlabbe 16309e6d18 Added StereoSGBM (fixed #77) (#318)
* Added StereoSGBM class

* fixed StereoSGBM build for OpenCV2
2018-10-04 16:10:16 -04:00
matlabbe a1079761e7 fixed #317 2018-10-04 11:06:47 -04:00
matlabbe 6b5990aa04 odom variance verification limited to yaw if 3dof registration/optimization is done 2018-10-02 18:02:55 -04:00
matlabbe ae08adb8bd warn odom high variance only one time 2018-10-02 15:32:26 -04:00
matlabbe 711184c465 Windows: Fixed linker error 2018-10-02 00:07:34 -04:00
matlabbe b5dec56eaf Parameters: added RGBD/LoopCovLimited, refactored "detect more loop closures" in MainWindow/DBViewer/rtabmap 2018-10-01 20:22:20 -04:00
matlabbe 0059a4bc1b Camera refactoring (#315)
* Camera Refactoring part 1 (Mac OS X)

* fixed camera*** -> Camera***

* Fixed build for cameras Zed/RealSense/RealSense2

* increased version to 0.17.7

* fixed build for cameras K4W2 and FlyCapture2
2018-10-01 19:33:56 -04:00
matlabbe eb38b9cfab Update README.md 2018-10-01 11:28:51 -04:00
matlabbe 459f0b7fa0 Update README.md 2018-09-30 16:13:04 -04:00
796 changed files with 109120 additions and 33395 deletions
+53 -11
View File
@@ -33,36 +33,41 @@ install:
- set OPENNI2_LIB64=C:\Program Files\OpenNI2\Lib - set OPENNI2_LIB64=C:\Program Files\OpenNI2\Lib
- set OPENNI2_REDIST64=C:\Program Files\OpenNI2\Redist - set OPENNI2_REDIST64=C:\Program Files\OpenNI2\Redist
# OpenCV # OpenCV
- ps: wget 'http://kent.dl.sourceforge.net/project/opencvlibrary/opencv-win/3.3.1/opencv-3.3.1-vc14.exe' -outfile opencv-3.3.1-vc14.exe #- appveyor-retry appveyor DownloadFile http://downloads.sourceforge.net/project/opencvlibrary/4.5.2/opencv-4.5.2-vc14_vc15.exe
- cmd: opencv-3.3.1-vc14.exe -o"C:\Program Files" -y #- cmd: opencv-4.5.2-vc14_vc15.exe -o"C:\Program Files" -y
#- ECHO "Installed OpenCV:"
#- ps: "ls \"C:/Program Files/opencv/build\""
#- set PATH=%PATH%;C:\Program Files\opencv\build\x64\vc14\bin
- ps: wget 'https://dl.dropboxusercontent.com/s/o6ofn491bc0jso1/opencv450_vc14.exe?dl=0' -outfile opencv.exe
- cmd: opencv.exe -o"C:\Program Files" -y
- ECHO "Installed OpenCV:" - ECHO "Installed OpenCV:"
- ps: "ls \"C:/Program Files/opencv/build\"" - ps: "ls \"C:/Program Files/opencv\""
- set PATH=%PATH%;C:\Program Files\opencv\build\x64\vc14\bin - set PATH=%PATH%;C:\Program Files\opencv\x64\vc14\bin
# VTK (including QVTK) # VTK (including QVTK)
- ps: wget 'https://dl.dropboxusercontent.com/s/1l33b5l3f3y52gf/VTK-6_3-msvc140.exe?dl=0' -outfile VTK-6_3.exe - ps: wget 'https://dl.dropboxusercontent.com/s/1l33b5l3f3y52gf/VTK-6_3-msvc140.exe?dl=0' -outfile VTK-6_3.exe
- cmd: VTK-6_3.exe -o"C:\Program Files" -y - cmd: VTK-6_3.exe -o"C:\Program Files" -y
- ECHO "Installed PCL:" - ECHO "Installed VTK:"
- ps: "ls \"C:/Program Files/VTK\"" - ps: "ls \"C:/Program Files/VTK\""
- set PATH=%PATH%;C:\Program Files\VTK\bin - set PATH=%PATH%;C:\Program Files\VTK\bin
# QHull # QHull
- ps: wget 'https://dl.dropboxusercontent.com/s/9widnk9msdsh2b8/Qhull-msvc140.exe?dl=0' -outfile Qhull.exe - ps: wget 'https://dl.dropboxusercontent.com/s/9widnk9msdsh2b8/Qhull-msvc140.exe?dl=0' -outfile Qhull.exe
- cmd: Qhull.exe -o"C:\Program Files" -y - cmd: Qhull.exe -o"C:\Program Files" -y
- ECHO "Installed PCL:" - ECHO "Installed QHull:"
- ps: "ls \"C:/Program Files/Qhull\"" - ps: "ls \"C:/Program Files/Qhull\""
- set PATH=%PATH%;C:\Program Files\Qhull\bin - set PATH=%PATH%;C:\Program Files\Qhull\bin
# FLANN # FLANN
- ps: wget 'https://dl.dropboxusercontent.com/s/7k58jbmqa51sxmh/FLANN-msvc140.exe?dl=0' -outfile FLANN.exe - ps: wget 'https://dl.dropboxusercontent.com/s/7k58jbmqa51sxmh/FLANN-msvc140.exe?dl=0' -outfile FLANN.exe
- cmd: FLANN.exe -o"C:\Program Files" -y - cmd: FLANN.exe -o"C:\Program Files" -y
- ECHO "Installed PCL:" - ECHO "Installed FLANN:"
- ps: "ls \"C:/Program Files/FLANN\"" - ps: "ls \"C:/Program Files/FLANN\""
- set PATH=%PATH%;C:\Program Files\FLANN\bin - set PATH=%PATH%;C:\Program Files\FLANN\bin
# Eigen # Eigen
- ps: wget 'https://dl.dropboxusercontent.com/s/3v6i9i8dxj4o8ji/Eigen.exe?dl=0' -outfile Eigen.exe - ps: wget 'https://dl.dropboxusercontent.com/s/3v6i9i8dxj4o8ji/Eigen.exe?dl=0' -outfile Eigen.exe
- cmd: Eigen.exe -o"C:\Program Files" -y - cmd: Eigen.exe -o"C:\Program Files" -y
- ECHO "Installed PCL:" - ECHO "Installed Eigen:"
- ps: "ls \"C:/Program Files/Eigen\"" - ps: "ls \"C:/Program Files/Eigen\""
# PCL # PCL
- ps: wget 'https://dl.dropboxusercontent.com/s/r9tvi9md54zlul2/PCL-1_8_1-July2018-msvc140.exe?dl=0' -outfile PCL_1.8.1.exe - ps: wget 'https://dl.dropboxusercontent.com/s/2iayr4lyqa50i9j/PCL_181_August2018_x64_vc14.exe?dl=0' -outfile PCL_1.8.1.exe
- cmd: PCL_1.8.1.exe -o"C:\Program Files" -y - cmd: PCL_1.8.1.exe -o"C:\Program Files" -y
- ECHO "Installed PCL:" - ECHO "Installed PCL:"
- ps: "ls \"C:/Program Files/PCL\"" - ps: "ls \"C:/Program Files/PCL\""
@@ -85,12 +90,49 @@ install:
- ECHO "Installed GTSAM:" - ECHO "Installed GTSAM:"
- ps: "ls \"C:/Program Files/GTSAM\"" - ps: "ls \"C:/Program Files/GTSAM\""
- set PATH=%PATH%;C:\Program Files\GTSAM\bin - set PATH=%PATH%;C:\Program Files\GTSAM\bin
# OctoMap
- ps: wget 'https://dl.dropboxusercontent.com/s/6jpxu0nm8ne6e54/octomap_x64_vc14.exe?dl=0' -outfile octomap.exe
- cmd: octomap.exe -o"C:\Program Files" -y
- ECHO "Installed OctoMap:"
- ps: "ls \"C:/Program Files/octomap-distribution\""
- set PATH=%PATH%;C:\Program Files\octomap-distribution\bin
# CPU-TSDF
- ps: wget 'https://dl.dropboxusercontent.com/s/mgges9va1uzxr0q/cpu_tsdf_sept2015_x64_vc14.exe?dl=0' -outfile cpu_tsdf.exe
- cmd: cpu_tsdf.exe -o"C:\Program Files" -y
- ECHO "Installed CPU-TSDF:"
- ps: "ls \"C:/Program Files/cpu_tsdf\""
- set PATH=%PATH%;C:\Program Files\cpu_tsdf\bin
# Open Chisel
- ps: wget 'https://dl.dropboxusercontent.com/s/0aaphcde4acrinm/open_chisel_x64_vc14.exe?dl=0' -outfile open_chisel.exe
- cmd: open_chisel.exe -o"C:\Program Files" -y
- ECHO "Installed Open Chisel:"
- ps: "ls \"C:/Program Files/open_chisel\""
- set PATH=%PATH%;C:\Program Files\open_chisel\bin
# yaml-cpp
- ps: wget 'https://dl.dropboxusercontent.com/s/22qfvftwj6zq8tj/yaml-cpp_x64_vc14.exe?dl=0' -outfile yaml-cpp.exe
- cmd: yaml-cpp.exe -o"C:\Program Files" -y
- ECHO "Installed yaml-cpp:"
- ps: "ls \"C:/Program Files/yaml-cpp\""
# RealSense2
- ps: wget 'https://github.com/IntelRealSense/librealsense/releases/download/v2.40.0/Intel.RealSense.SDK-WIN10-2.40.0.2482.exe' -outfile realsense2.exe
- cmd: realsense2.exe /VERYSILENT
- ECHO "Installed RealSense2:"
- ps: "ls \"C:/Program Files (x86)/Intel RealSense SDK 2.0\""
- set PATH=%PATH%;C:\Program Files (x86)\Intel RealSense SDK 2.0\bin\x64
- set RealSense2_ROOT_DIR=C:\Program Files (x86)\Intel RealSense SDK 2.0
# Kinect 4 Azure
- ps: wget 'https://download.microsoft.com/download/3/d/6/3d6d9e99-a251-4cf3-8c6a-8e108e960b4b/Azure%20Kinect%20SDK%201.4.1.exe' -outfile azure.exe
- cmd: azure.exe /quiet
- ECHO "Installed Kinect For Azure:"
- ps: "ls \"C:/Program Files/Azure Kinect SDK v1.4.1\""
- set PATH=%PATH%;C:\Program Files\Azure Kinect SDK v1.4.1\tools
- set K4A_ROOT_DIR=C:\Program Files\Azure Kinect SDK v1.4.1
before_build: before_build:
- cd c:\projects\rtabmap\build - cd c:\projects\rtabmap\build
- ECHO %PROGRAMFILES% - ECHO %PROGRAMFILES%
- ECHO %PATH% - ECHO %PATH%
- cmake -G "Visual Studio 14 2015 Win64" -DOpenCV_DIR="C:\Program Files\opencv\build" -DPCL_DIR="C:\Program Files\PCL\cmake" -DZLIB_ROOT="C:\Program Files\zlib" -DBUILD_AS_BUNDLE=ON .. - cmake -G "Visual Studio 14 2015 Win64" -DOpenCV_DIR="C:\Program Files\opencv\build" -DPCL_DIR="C:\Program Files\PCL\cmake" -DCPUTSDF_DIR="C:\Program Files\cpu_tsdf\share\cpu_tsdf" -Dyaml-cpp_DIR="C:\Program Files\yaml-cpp\CMake" -DBUILD_AS_BUNDLE=ON ..
after_build : after_build :
- cmake --build . --config Release --target package - cmake --build . --config Release --target package
@@ -101,7 +143,7 @@ artifacts:
notifications: notifications:
- provider: Email - provider: Email
to: to:
- matlabbe@email.com - matlabbe@gmail.com
on_build_success: false on_build_success: false
on_build_failure: false on_build_failure: false
on_build_status_changed: true on_build_status_changed: true
+1
View File
@@ -0,0 +1 @@
build/*
+66
View File
@@ -0,0 +1,66 @@
name: CMake-ROS
on:
push:
branches:
- master
pull_request:
branches:
- '**'
env:
# Customize the CMake build type here (Release, Debug, RelWithDebInfo, etc.)
BUILD_TYPE: Release
jobs:
build:
# The CMake configure and build commands are platform agnostic and should work equally
# well on Windows or Mac. You can convert this to a matrix build if you need
# cross-platform coverage.
# See: https://docs.github.com/en/free-pro-team@latest/actions/learn-github-actions/managing-complex-workflows#using-a-build-matrix
name: Build on ros ${{ matrix.ros_distribution }} and ${{ matrix.os }}
runs-on: ${{ matrix.os }}
strategy:
matrix:
ros_distribution: [ noetic, foxy, humble, rolling]
include:
- ros_distribution: 'noetic'
os: ubuntu-20.04
- ros_distribution: 'foxy'
os: ubuntu-20.04
- ros_distribution: 'humble'
os: ubuntu-22.04
- ros_distribution: 'rolling'
os: ubuntu-22.04
steps:
- name: Workaround dpkg grub-efi-amd64-signed error
run: |
sudo apt-mark hold grub-efi-amd64-signed
- uses: ros-tooling/setup-ros@v0.5
with:
required-ros-distributions: ${{ matrix.ros_distribution }}
- uses: actions/checkout@v2
- name: Install dependencies
run: |
source /opt/ros/${{ matrix.ros_distribution }}/setup.bash
rosdep update
rosdep install --from-paths ${{github.workspace}} -y
- name: Configure CMake
run: |
source /opt/ros/${{ matrix.ros_distribution }}/setup.bash
cmake -B ${{github.workspace}}/build -DCMAKE_BUILD_TYPE=${{env.BUILD_TYPE}}
- name: Build
run: cmake --build ${{github.workspace}}/build --config ${{env.BUILD_TYPE}}
- name: Info
working-directory: ${{github.workspace}}/build/bin
run: |
source /opt/ros/${{ matrix.ros_distribution }}/setup.bash
./rtabmap-console --version
+48
View File
@@ -0,0 +1,48 @@
name: CMake
on:
push:
branches:
- master
pull_request:
branches:
- '**'
env:
BUILD_TYPE: Release
jobs:
build:
name: ${{ matrix.os }}
runs-on: ${{ matrix.os }}
strategy:
matrix:
os: [ubuntu-22.04, ubuntu-20.04]
steps:
- name: Install dependencies
run: |
DEBIAN_FRONTEND=noninteractive
sudo apt-get update
sudo apt-get -y install libopencv-dev libpcl-dev git cmake software-properties-common libyaml-cpp-dev
- uses: actions/checkout@v2
- name: Configure CMake
run: |
cmake -B ${{github.workspace}}/build -DCMAKE_BUILD_TYPE=${{env.BUILD_TYPE}}
- name: Build
run: cmake --build ${{github.workspace}}/build --config ${{env.BUILD_TYPE}}
- name: Info
working-directory: ${{github.workspace}}/build/bin
run: |
./rtabmap-console --version
# - name: Test
# working-directory: ${{github.workspace}}/build
# # Execute tests defined by the CMake configuration.
# # See https://cmake.org/cmake/help/latest/manual/ctest.1.html for more detail
# run: ctest -C ${{env.BUILD_TYPE}}
+131
View File
@@ -0,0 +1,131 @@
name: docker
on:
push:
branches:
- 'master'
jobs:
docker:
runs-on: ubuntu-latest
strategy:
matrix:
docker_tag: [xenial, bionic, focal, focal-foxy, jammy, android23, android24, android26, android30]
include:
- docker_tag: xenial
docker_tags: |
introlab3it/rtabmap:xenial
introlab3it/rtabmap:16.04
docker_args: |
NOT_USED=0
docker_platforms: |
linux/amd64
docker_path: 'xenial'
- docker_tag: bionic
docker_tags: |
introlab3it/rtabmap:bionic
introlab3it/rtabmap:18.04
docker_args: |
NOT_USED=0
docker_platforms: |
linux/amd64
linux/arm64
docker_path: 'bionic'
- docker_tag: focal
docker_tags: |
introlab3it/rtabmap:focal
introlab3it/rtabmap:20.04
introlab3it/rtabmap:latest
docker_args: |
NOT_USED=0
docker_platforms: |
linux/amd64
linux/arm64
docker_path: 'focal'
- docker_tag: focal-foxy
docker_tags: |
introlab3it/rtabmap:focal-foxy
introlab3it/rtabmap:20.04-foxy
docker_args: |
NOT_USED=0
docker_platforms: |
linux/amd64
linux/arm64
docker_path: 'focal-foxy'
- docker_tag: jammy
docker_tags: |
introlab3it/rtabmap:jammy
introlab3it/rtabmap:22.04
docker_args: |
NOT_USED=0
docker_platforms: |
linux/amd64
linux/arm64
docker_path: 'jammy'
- docker_tag: android23
docker_tags: |
introlab3it/rtabmap:android23
introlab3it/rtabmap:tango
docker_args: |
API_VERSION=23
docker_platforms: |
linux/amd64
docker_path: 'bionic/android/rtabmap_apiXX'
- docker_tag: android24
docker_tags: |
introlab3it/rtabmap:android24
docker_args: |
API_VERSION=24
docker_platforms: |
linux/amd64
docker_path: 'bionic/android/rtabmap_apiXX'
- docker_tag: android26
docker_tags: |
introlab3it/rtabmap:android26
docker_args: |
API_VERSION=26
docker_platforms: |
linux/amd64
docker_path: 'bionic/android/rtabmap_apiXX'
- docker_tag: android30
docker_tags: |
introlab3it/rtabmap:android30
docker_args: |
API_VERSION=30
docker_platforms: |
linux/amd64
docker_path: 'bionic/android/rtabmap_apiXX'
steps:
-
name: Checkout
uses: actions/checkout@v2
-
name: Set up QEMU
uses: docker/setup-qemu-action@v1
with:
platforms: all
-
name: Set up Docker Buildx
uses: docker/setup-buildx-action@v1
-
name: Login to DockerHub
uses: docker/login-action@v1
with:
username: ${{ secrets.DOCKERHUB_USERNAME }}
password: ${{ secrets.DOCKERHUB_TOKEN }}
-
name: Build and push
uses: docker/build-push-action@v2
with:
context: .
push: true
platforms: ${{ matrix.docker_platforms }}
file: ./docker/${{ matrix.docker_path }}/Dockerfile
build-args: |
${{ matrix.docker_args }}
tags: ${{ matrix.docker_tags }}
cache-from: type=registry,ref=introlab3it/rtabmap:${{ matrix.docker_tag }}
cache-to: type=inline
+4
View File
@@ -8,3 +8,7 @@ app/android/.classpath
app/android/.project app/android/.project
app/android/AndroidManifest.xml app/android/AndroidManifest.xml
app/android/res/raw/ app/android/res/raw/
compile_flags.txt
tags
build_*
*.bak
-34
View File
@@ -1,34 +0,0 @@
sudo: true
dist: trusty
language: cpp
group: deprecated-2017Q3
compiler:
- gcc
- clang
addons:
apt:
packages:
- cmake
- libopencv-dev
- libqt4-dev
- libsqlite3-dev
- libyaml-cpp-dev
install:
- sudo sh -c 'echo "deb http://packages.ros.org/ros/ubuntu trusty main" > /etc/apt/sources.list.d/ros-latest.list'
- wget http://packages.ros.org/ros.key -O - | sudo apt-key add -
- sudo apt-get update
- sudo apt-get update && sudo apt-get install dpkg
- sudo apt-get -y install libpcl-1.7-all libfreenect-dev ros-indigo-libg2o ros-indigo-octomap libopenni2-dev
script:
- source /opt/ros/indigo/setup.bash
- mkdir -p build && cd build
- cmake ..
- make
notifications:
email:
- matlabbe@gmail.com
+869 -292
View File
File diff suppressed because it is too large Load Diff
+5 -4
View File
@@ -1,5 +1,6 @@
Copyright (c) 2010-2016, Mathieu Labbe - IntRoLab - Universite de Sherbrooke RTAB-Map - https://github.com/introlab/rtabmap
All rights reserved. Copyright (c) 2010-2021, Mathieu Labbe - IntRoLab - Universite de Sherbrooke, all rights reserved.
Copyright (c) XXX, contributors, all rights reserved.
Redistribution and use in source and binary forms, with or without Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met: modification, are permitted provided that the following conditions are met:
@@ -11,7 +12,7 @@ modification, are permitted provided that the following conditions are met:
this list of conditions and the following disclaimer in the documentation this list of conditions and the following disclaimer in the documentation
and/or other materials provided with the distribution. and/or other materials provided with the distribution.
* Neither the name of the Universite de Sherbrooke nor the names of its * Neither the name of the copyright holders nor the names of the
contributors may be used to endorse or promote products derived from contributors may be used to endorse or promote products derived from
this software without specific prior written permission. this software without specific prior written permission.
@@ -24,4 +25,4 @@ DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 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 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. OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+60 -4
View File
@@ -1,13 +1,12 @@
rtabmap ![Analytics](https://ga-beacon.appspot.com/UA-56986679-3/github-main?pixel) rtabmap
======= =======
[![RTAB-Map Logo](https://raw.githubusercontent.com/introlab/rtabmap/master/guilib/src/images/RTAB-Map100.png)](http://introlab.github.io/rtabmap) [![RTAB-Map Logo](https://raw.githubusercontent.com/introlab/rtabmap/master/guilib/src/images/RTAB-Map100.png)](http://introlab.github.io/rtabmap)
[![Release][release-image]][releases] [![Release][release-image]][releases]
[![License][license-image]][license] [![License][license-image]][license]
Linux: [![Build Status](https://travis-ci.org/introlab/rtabmap.svg?branch=master)](https://travis-ci.org/introlab/rtabmap) Windows: [![Build status](https://ci.appveyor.com/api/projects/status/hr73xspix9oqa26h/branch/master?svg=true)](https://ci.appveyor.com/project/matlabbe/rtabmap/branch/master)
[release-image]: https://img.shields.io/badge/release-0.16.3-green.svg?style=flat [release-image]: https://img.shields.io/badge/release-0.20.16-green.svg?style=flat
[releases]: https://github.com/introlab/rtabmap/releases [releases]: https://github.com/introlab/rtabmap/releases
[license-image]: https://img.shields.io/badge/license-BSD-green.svg?style=flat [license-image]: https://img.shields.io/badge/license-BSD-green.svg?style=flat
@@ -15,6 +14,63 @@ Linux: [![Build Status](https://travis-ci.org/introlab/rtabmap.svg?branch=master
RTAB-Map library and standalone application. RTAB-Map library and standalone application.
For more information, visit the [RTAB-Map's home page](http://introlab.github.io/rtabmap) or the [RTAB-Map's wiki](https://github.com/introlab/rtabmap/wiki). * For more information (e.g., papers, major updates), visit [RTAB-Map's home page](http://introlab.github.io/rtabmap).
* For installation instructions and examples, visit [RTAB-Map's wiki](https://github.com/introlab/rtabmap/wiki).
To use RTAB-Map under ROS, visit the [rtabmap](http://wiki.ros.org/rtabmap) page on the ROS wiki. To use RTAB-Map under ROS, visit the [rtabmap](http://wiki.ros.org/rtabmap) page on the ROS wiki.
### Acknowledgements
This project is supported by [IntRoLab - Intelligent / Interactive / Integrated / Interdisciplinary Robot Lab](https://introlab.3it.usherbrooke.ca/), Sherbrooke, Québec, Canada.
<a href="https://introlab.3it.usherbrooke.ca/">
<img src="https://github.com/introlab/16SoundsUSB/blob/master/images/IntRoLab.png" alt="IntRoLab" height="100">
</a>
#### CI Latest
<table>
<tbody>
<tr>
<td>Linux</td>
<td><a href="https://github.com/introlab/rtabmap/actions/workflows/cmake.yml"><img src="https://github.com/introlab/rtabmap/actions/workflows/cmake.yml/badge.svg" alt="Build Status"/> <br> <a href="https://github.com/introlab/rtabmap/actions/workflows/cmake-ros.yml"><img src="https://github.com/introlab/rtabmap/actions/workflows/cmake-ros.yml/badge.svg" alt="Build Status"/> <br> <a href="https://github.com/introlab/rtabmap/actions/workflows/docker.yml"><img src="https://github.com/introlab/rtabmap/actions/workflows/docker.yml/badge.svg" alt="Build Status"/>
</td>
</tr>
<tr>
<td>Windows</td>
<td><a href="https://ci.appveyor.com/project/matlabbe/rtabmap/branch/master"><img src="https://ci.appveyor.com/api/projects/status/hr73xspix9oqa26h/branch/master?svg=true" alt="Build Status"/>
</td>
</tr>
</tbody>
</table>
#### ROS Binaries
`ros-$ROS_DISTRO-rtabmap`
<table>
<tbody>
<tr>
<td rowspan="2">ROS 1</td>
<td>Melodic</td>
<td><a href="http://build.ros.org/job/Mbin_ubv8_uBv8__rtabmap__ubuntu_bionic_arm64__binary/"><img src="http://build.ros.org/buildStatus/icon?job=Mbin_ubv8_uBv8__rtabmap__ubuntu_bionic_arm64__binary" alt="Build Status"/></td>
</tr>
<tr>
<td>Noetic</td>
<td><a href="http://build.ros.org/job/Nbin_ufv8_uFv8__rtabmap__ubuntu_focal_arm64__binary/"><img src="http://build.ros.org/buildStatus/icon?job=Nbin_ufv8_uFv8__rtabmap__ubuntu_focal_arm64__binary" alt="Build Status"/></td>
</tr>
<tr>
<td rowspan="3">ROS 2</td>
<td>Foxy</td>
<td><a href="http://build.ros2.org/job/Fbin_uF64__rtabmap__ubuntu_focal_amd64__binary/"><img src="http://build.ros2.org/buildStatus/icon?job=Fbin_uF64__rtabmap__ubuntu_focal_amd64__binary" alt="Build Status"/></td>
</tr>
<tr>
<td>Humble</td>
<td><a href="http://build.ros2.org/job/Hbin_uJ64__rtabmap__ubuntu_jammy_amd64__binary/"><img src="http://build.ros2.org/buildStatus/icon?job=Hbin_uJ64__rtabmap__ubuntu_jammy_amd64__binary" alt="Build Status"/></td>
</tr>
<tr>
<td>Rolling</td>
<td><a href="http://build.ros2.org/job/Rbin_uJ64__rtabmap__ubuntu_jammy_amd64__binary/"><img src="http://build.ros2.org/buildStatus/icon?job=Rbin_uJ64__rtabmap__ubuntu_jammy_amd64__binary" alt="Build Status"/></td>
</tr>
</tbody>
</table>
+78 -83
View File
@@ -1,96 +1,91 @@
# - Config file for the RTABMap package include(CMakeFindDependencyMacro)
# Components:
# core (required)
# gui (optional)
# utilite (required)
# It defines the following variables
# RTABMap_INCLUDE_DIRS - include directories for RTABMap
# RTABMap_LIBRARIES - libraries to link against
# RTABMap_CORE - core library
# RTABMap_UTILITE - utilite library
# RTABMap_GUI - gui library (set if RTABMap is built with Qt)
# Compute paths # Mandatory dependencies
get_filename_component(RTABMap_CMAKE_DIR "${CMAKE_CURRENT_LIST_FILE}" PATH) find_dependency(OpenCV COMPONENTS core calib3d imgproc highgui stitching photo video OPTIONAL_COMPONENTS aruco xfeatures2d nonfree gpu cudafeatures2d)
set(RTABMap_INCLUDE_DIRS "@CONF_INCLUDE_DIRS@")
#core lib if(EXISTS "${CMAKE_CURRENT_LIST_DIR}/RTABMap_guiTargets.cmake")
find_library(RTABMap_CORE_RELEASE NAMES rtabmap_core NO_DEFAULT_PATH HINTS @CONF_LIB_DIR@) find_dependency(PCL 1.7 COMPONENTS common io kdtree search surface filters registration sample_consensus segmentation visualization)
find_library(RTABMap_CORE_DEBUG NAMES rtabmap_cored NO_DEFAULT_PATH HINTS @CONF_LIB_DIR@)
if(@CONF_QT_VERSION@ EQUAL 6)
IF(RTABMap_CORE_DEBUG AND RTABMap_CORE_RELEASE) find_dependency(Qt6 COMPONENTS Widgets Core Gui OpenGL)
SET(RTABMap_CORE elseif(@CONF_QT_VERSION@ EQUAL 5)
debug ${RTABMap_CORE_DEBUG} find_dependency(Qt5 COMPONENTS Widgets Core Gui OpenGL)
optimized ${RTABMap_CORE_RELEASE} else() # Qt4
) find_dependency(Qt4 COMPONENTS QtCore QtGui)
ELSEIF(RTABMap_CORE_DEBUG) endif()
SET(RTABMap_CORE ${RTABMap_CORE_DEBUG}) set(RTABMap_QT_VERSION @CONF_QT_VERSION@)
ELSE() ELSE()
SET(RTABMap_CORE ${RTABMap_CORE_RELEASE}) find_dependency(PCL 1.7 COMPONENTS common io kdtree search surface filters registration sample_consensus segmentation)
ENDIF()
set(RTABMap_DEFINITIONS ${PCL_DEFINITIONS})
add_definitions(${RTABMap_DEFINITIONS}) # To include -march=native if set
# Optional dependencies
IF(EXISTS "${CMAKE_CURRENT_LIST_DIR}/@CONF_MODULES_DIR@")
list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_LIST_DIR}/@CONF_MODULES_DIR@")
ENDIF() ENDIF()
#utilite lib IF(@CONF_WITH_REALSENSE2@)
find_library(RTABMap_UTILITE_RELEASE NAMES rtabmap_utilite NO_DEFAULT_PATH HINTS @CONF_LIB_DIR@) IF(WIN32)
find_library(RTABMap_UTILITE_DEBUG NAMES rtabmap_utilited NO_DEFAULT_PATH HINTS @CONF_LIB_DIR@) find_dependency(RealSense2)
ELSE()
IF(RTABMap_UTILITE_DEBUG AND RTABMap_UTILITE_RELEASE) find_dependency(realsense2)
SET(RTABMap_UTILITE ENDIF()
debug ${RTABMap_UTILITE_DEBUG}
optimized ${RTABMap_UTILITE_RELEASE}
)
ELSEIF(RTABMap_UTILITE_DEBUG)
SET(RTABMap_UTILITE ${RTABMap_UTILITE_DEBUG})
ELSE()
SET(RTABMap_UTILITE ${RTABMap_UTILITE_RELEASE})
ENDIF() ENDIF()
set(RTABMap_LIBRARIES ${RTABMap_CORE} ${RTABMap_UTILITE}) IF(@CONF_WITH_K4A@)
IF(WIN32)
find_dependency(K4A)
ELSE()
find_dependency(k4a)
find_dependency(k4arecord)
ENDIF()
ENDIF()
list(LENGTH RTABMap_FIND_COMPONENTS RTABMap_FIND_COMPONENTS_LENGTH) IF(@CONF_WITH_OCTOMAP@)
set(WITH_GUI ON) find_dependency(octomap)
if(${RTABMap_FIND_COMPONENTS_LENGTH} GREATER 0) ENDIF()
list (FIND RTABMap_FIND_COMPONENTS "gui" _index)
if (${_index} EQUAL -1)
set(WITH_GUI OFF)
endif()
endif(${RTABMap_FIND_COMPONENTS_LENGTH} GREATER 0)
# Provide those for backward compatibilities (e.g., catkin requires them to propagate dependencies)
set(RTABMap_INCLUDE_DIRS "")
set(RTABMap_LIBRARIES "")
set(RTABMap_TARGETS "")
#gui lib (OFF if RTAB-Map is not built with Qt) set(_RTABMap_supported_components utilite core gui)
if(@CONF_WITH_GUI@ AND ${WITH_GUI})
find_library(RTABMap_GUI_RELEASE NAMES rtabmap_gui NO_DEFAULT_PATH HINTS @CONF_LIB_DIR@)
find_library(RTABMap_GUI_DEBUG NAMES rtabmap_guid NO_DEFAULT_PATH HINTS @CONF_LIB_DIR@)
IF(RTABMap_GUI_DEBUG AND RTABMap_GUI_RELEASE)
SET(RTABMap_GUI
debug ${RTABMap_GUI_DEBUG}
optimized ${RTABMap_GUI_RELEASE}
)
ELSEIF(RTABMap_GUI_RELEASE)
SET(RTABMap_GUI ${RTABMap_GUI_RELEASE})
ELSEIF(RTABMap_GUI_DEBUG)
SET(RTABMap_GUI ${RTABMap_GUI_DEBUG})
ENDIF()
set(RTABMap_LIBRARIES ${RTABMap_LIBRARIES} ${RTABMap_GUI})
elseif(${WITH_GUI})
MESSAGE(ERROR "Asked for \"gui\" module but RTABMap hasn't been built with gui support.")
endif()
# Dependencies foreach(_comp ${_RTABMap_supported_components})
if(@CONF_VTK_QT@ AND ${WITH_GUI}) if(EXISTS "${CMAKE_CURRENT_LIST_DIR}/RTABMap_${_comp}Targets.cmake")
find_package(VTK COMPONENTS vtkGUISupportQt NO_MODULE) # to define vtkGUISupportQt target include("${CMAKE_CURRENT_LIST_DIR}/RTABMap_${_comp}Targets.cmake")
endif(@CONF_VTK_QT@ AND ${WITH_GUI}) set(RTABMap_${_comp}_FOUND True)
SET(RTABMap_LIBRARIES ${RTABMap_LIBRARIES} "@CONF_DEPENDENCIES@") set(RTABMap_TARGETS
${RTABMap_TARGETS}
rtabmap::${_comp})
get_target_property(RTABMap_${_comp}_INCLUDE_DIRS rtabmap::${_comp} INTERFACE_INCLUDE_DIRECTORIES)
get_target_property(RTABMap_${_comp}_LIBRARIES rtabmap::${_comp} INTERFACE_LINK_LIBRARIES)
set(RTABMap_INCLUDE_DIRS
${RTABMap_INCLUDE_DIRS}
${RTABMap_${_comp}_INCLUDE_DIRS})
set(RTABMap_LIBRARIES
${RTABMap_LIBRARIES}
rtabmap::${_comp})
if(RTABMap_${_comp}_LIBRARIES)
set(RTABMap_LIBRARIES
${RTABMap_LIBRARIES}
${RTABMap_${_comp}_LIBRARIES})
endif()
else()
set(RTABMap_${_comp}_FOUND False)
endif()
endforeach()
#backward compatibilities include("${CMAKE_CURRENT_LIST_DIR}/RTABMapTargets.cmake")
set(RTABMAP_CORE ${RTABMap_CORE})
set(RTABMAP_UTILITE ${RTABMap_UTILITE})
if(RTABMap_GUI)
set(RTABMAP_GUI ${RTABMap_GUI})
set(RTABMAP_QT_VERSION @CONF_QT_VERSION@)
endif(RTABMap_GUI)
include(FindPackageHandleStandardArgs) foreach(_comp ${RTABMap_FIND_COMPONENTS})
find_package_handle_standard_args(RTABMap DEFAULT_MSG RTABMap_LIBRARIES RTABMap_INCLUDE_DIRS) if (NOT ";${_RTABMap_supported_components};" MATCHES ";${_comp};")
mark_as_advanced(RTABMap_LIBRARIES RTABMap_INCLUDE_DIRS RTABMap_LIBRARY_DIRS) set(RTABMap_${_comp}_FOUND False)
if(${RTABMap_FIND_REQUIRED_${_comp}})
set(RTABMap_FOUND False)
set(RTABMap_NOT_FOUND_MESSAGE "Unsupported or not found required component: ${_comp}")
endif()
endif()
endforeach()
-11
View File
@@ -1,11 +0,0 @@
set(PACKAGE_VERSION "@RTABMAP_VERSION@")
# Check whether the requested PACKAGE_FIND_VERSION is compatible
if("${PACKAGE_VERSION}" VERSION_LESS "${PACKAGE_FIND_VERSION}")
set(PACKAGE_VERSION_COMPATIBLE FALSE)
else()
set(PACKAGE_VERSION_COMPATIBLE TRUE)
if ("${PACKAGE_VERSION}" VERSION_EQUAL "${PACKAGE_FIND_VERSION}")
set(PACKAGE_VERSION_EXACT TRUE)
endif()
endif()
+33 -3
View File
@@ -40,32 +40,62 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
@NONFREE@#define RTABMAP_NONFREE @NONFREE@#define RTABMAP_NONFREE
@TORO@#define RTABMAP_TORO @TORO@#define RTABMAP_TORO
@G2O@#define RTABMAP_G2O @G2O@#define RTABMAP_G2O
@G2O_CPP_CONF@#define RTABMAP_G2O_CPP11 @G2O_CPP_CONF@#define RTABMAP_G2O_CPP11 @G2O_CPP11@
@GTSAM@#define RTABMAP_GTSAM @GTSAM@#define RTABMAP_GTSAM
@CERES@#define RTABMAP_CERES
@MRPT@#define RTABMAP_MRPT
@VERTIGO@#define RTABMAP_VERTIGO @VERTIGO@#define RTABMAP_VERTIGO
@OPENCV3@#define RTABMAP_OPENCV3
@OPENNI2@#define RTABMAP_OPENNI2 @OPENNI2@#define RTABMAP_OPENNI2
@FREENECT@#define RTABMAP_FREENECT @FREENECT@#define RTABMAP_FREENECT
@FREENECT2@#define RTABMAP_FREENECT2 @FREENECT2@#define RTABMAP_FREENECT2
@K4W2@#define RTABMAP_K4W2 @K4W2@#define RTABMAP_K4W2
@K4A@#define RTABMAP_K4A
@CVSBA@#define RTABMAP_CVSBA @CVSBA@#define RTABMAP_CVSBA
@POINTMATCHER@#define RTABMAP_POINTMATCHER @POINTMATCHER@#define RTABMAP_POINTMATCHER
@CCCORELIB@#define RTABMAP_CCCORELIB
@OPEN3D@#define RTABMAP_OPEN3D
@FASTCV@#define RTABMAP_FASTCV
@OPENGV@#define RTABMAP_OPENGV
@PDAL@#define RTABMAP_PDAL
@LOAM@#define RTABMAP_LOAM @LOAM@#define RTABMAP_LOAM
@FLOAM@#define RTABMAP_FLOAM
@DC1394@#define RTABMAP_DC1394 @DC1394@#define RTABMAP_DC1394
@FLYCAPTURE2@#define RTABMAP_FLYCAPTURE2 @FLYCAPTURE2@#define RTABMAP_FLYCAPTURE2
@ZED@#define RTABMAP_ZED @ZED@#define RTABMAP_ZED
@ZEDOC@#define RTABMAP_ZEDOC
@REALSENSE@#define RTABMAP_REALSENSE @REALSENSE@#define RTABMAP_REALSENSE
@REALSENSESLAM@#define RTABMAP_REALSENSE_SLAM @REALSENSESLAM@#define RTABMAP_REALSENSE_SLAM
@REALSENSE2@#define RTABMAP_REALSENSE2 @REALSENSE2@#define RTABMAP_REALSENSE2
@MYNTEYE@#define RTABMAP_MYNTEYE
@DEPTHAI@#define RTABMAP_DEPTHAI
@OCTOMAP@#define RTABMAP_OCTOMAP @OCTOMAP@#define RTABMAP_OCTOMAP
@CPUTSDF@#define RTABMAP_CPUTSDF @CPUTSDF@#define RTABMAP_CPUTSDF
@ALICE_VISION@#define RTABMAP_ALICE_VISION
@OPENCHISEL@#define RTABMAP_OPENCHISEL @OPENCHISEL@#define RTABMAP_OPENCHISEL
@FOVIS@#define RTABMAP_FOVIS @FOVIS@#define RTABMAP_FOVIS
@VISO2@#define RTABMAP_VISO2 @VISO2@#define RTABMAP_VISO2
@DVO@#define RTABMAP_DVO @DVO@#define RTABMAP_DVO
@OKVIS@#define RTABMAP_OKVIS @OKVIS@#define RTABMAP_OKVIS
@MSCKF_VIO@#define RTABMAP_MSCKF_VIO @MSCKF_VIO@#define RTABMAP_MSCKF_VIO
@ORB_SLAM2@#define RTABMAP_ORB_SLAM2 @VINS@#define RTABMAP_VINS
@OPENVINS@#define RTABMAP_OPENVINS
@ORB_SLAM@#define RTABMAP_ORB_SLAM @ORB_SLAM_VERSION@
@ORB_OCTREE@#define RTABMAP_ORB_OCTREE
@TORCH@#define RTABMAP_TORCH
@PYTHON@#define RTABMAP_PYTHON
@MADGWICK@#define RTABMAP_MADGWICK
#include <pcl/pcl_config.h>
#if PCL_VERSION_COMPARE(>, 1, 11, 1)
#include <pcl/types.h>
#define RTABMAP_PCL_INDEX pcl::index_t
#elif PCL_VERSION_COMPARE(>=, 1, 10, 0)
#define RTABMAP_PCL_INDEX std::uint32_t
#else
#include <pcl/pcl_macros.h>
#define RTABMAP_PCL_INDEX pcl::uint32_t
#endif
#endif /* VERSION_H_ */ #endif /* VERSION_H_ */
+1
View File
@@ -1 +1,2 @@
/bin/ /bin/
/gen/
+43 -7
View File
@@ -2,22 +2,26 @@
<!-- 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="70" android:versionCode="72"
android:versionName="@RTABMAP_VERSION@"> android:versionName="@RTABMAP_VERSION@">
<uses-permission android:name="android.permission.CAMERA" /> <uses-permission android:name="android.permission.CAMERA" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" /> <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" /> <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.READ_FRAME_BUFFER" />
<uses-permission android:name="android.permission.ACCESS_SURFACE_FLINGER" />
<uses-permission android:name="android.permission.INTERNET" /> <uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" /> <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" /> <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
<uses-feature android:name="android.hardware.location.gps" /> <uses-feature android:name="android.hardware.location.gps" />
<uses-feature android:glEsVersion="0x00020000" /> <uses-feature android:glEsVersion="0x00020000" />
<!-- This is the platform API where NativeActivity was introduced. --> <!-- This is the platform API where depth16 support in android was introduced. -->
<uses-sdk android:minSdkVersion="19" /> <uses-sdk android:minSdkVersion="@ANDROID_NATIVE_API_LEVEL@" />
<queries>
<package android:name="com.google.ar.core" />
<package android:name="com.huawei.ar.engine" />
</queries>
<!-- This .apk has no Java code itself, so set hasCode to false. --> <!-- This .apk has no Java code itself, so set hasCode to false. -->
<application <application
@@ -25,7 +29,9 @@
android:icon="@drawable/ic_launcher" android:icon="@drawable/ic_launcher"
android:debuggable="@ANDROID_DEBUGGABLE@"> android:debuggable="@ANDROID_DEBUGGABLE@">
<uses-library android:name="com.projecttango.libtango_device2" android:required="true" /> <uses-library android:name="com.projecttango.libtango_device2" android:required="false" />
<meta-data android:name="com.google.ar.core" android:value="optional" />
<meta-data android:name="com.huawei.ar.engine" android:value="optional" />
<!-- 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. -->
@@ -41,11 +47,41 @@
<intent-filter> <intent-filter>
<action android:name="android.intent.action.MAIN" /> <action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" /> <category android:name="android.intent.category.LAUNCHER" />
</intent-filter> </intent-filter>
<intent-filter>
<action android:name="android.intent.action.SEND" />
<action android:name="android.intent.action.SEND_MULTIPLE" />
<action android:name="android.intent.action.OPEN_DOCUMENT" />
<category android:name="android.intent.category.DEFAULT" />
<data android:mimeType="application/octet-stream" />
<data android:pathPattern=".*\.db" />
</intent-filter>
</activity> </activity>
<activity android:name="SettingsActivity" android:label="@string/settings" android:screenOrientation="fullSensor"/> <activity android:name="SettingsActivity" android:label="@string/settings" android:screenOrientation="fullSensor"/>
<activity android:name="SketchfabActivity" android:label="@string/sketchfab" android:screenOrientation="fullSensor"/> <activity android:name="SketchfabActivity" android:label="@string/sketchfab" android:screenOrientation="fullSensor"/>
<meta-data
android:name="com.google.ar.core.min_apk_version"
android:value="191106000" /> <!-- This activity is critical for installing ARCore when it is not already present. -->
<activity
android:name="com.google.ar.core.InstallActivity"
android:configChanges="keyboardHidden|orientation|screenSize"
android:excludeFromRecents="true"
android:exported="false"
android:launchMode="singleTop"
android:theme="@android:style/Theme.Material.Light.Dialog.Alert" />
<provider
android:name="android.support.v4.content.FileProvider"
android:authorities="com.introlab.rtabmap.provider"
android:exported="false"
android:grantUriPermissions="true">
<meta-data
android:name="android.support.FILE_PROVIDER_PATHS"
android:resource="@xml/provider_paths"/>
</provider>
</application> </application>
</manifest> </manifest>
+88 -2
View File
@@ -1,10 +1,95 @@
option(WITH_TANGO "Include Tango support" ON)
option(WITH_ARCORE "Include ARCore support" ON)
option(WITH_ARENGINE "Include AREngine support" ON)
option(DISABLE_LOG "Disable Android logging (should be true in release)" ON) option(DISABLE_LOG "Disable Android logging (should be true in release)" ON)
option(DEPTH_TEST "Enable depth test on ARCore" OFF)
# Google Tango needs access to system shared
# libraries (e.g. libbinder.so) that are not accessible
# with android >=24
IF(WITH_TANGO AND ${ANDROID_NATIVE_API_LEVEL} LESS 24)
FIND_PACKAGE(Tango QUIET)
IF(Tango_FOUND)
MESSAGE(STATUS "Found Tango: ${Tango_INCLUDE_DIRS}")
ENDIF(Tango_FOUND)
ENDIF(WITH_TANGO AND ${ANDROID_NATIVE_API_LEVEL} LESS 24)
IF(WITH_ARCORE AND ${ANDROID_NATIVE_API_LEVEL} GREATER 22)
FIND_PACKAGE(ARCore QUIET)
IF(ARCore_FOUND)
MESSAGE(STATUS "Found ARCore: ${ARCore_INCLUDE_DIRS}")
ENDIF(ARCore_FOUND)
ENDIF(WITH_ARCORE AND ${ANDROID_NATIVE_API_LEVEL} GREATER 22)
IF(WITH_ARENGINE AND ${ANDROID_NATIVE_API_LEVEL} GREATER 23)
FIND_PACKAGE(AREngine QUIET)
IF(AREngine_FOUND)
MESSAGE(STATUS "Found AREngine: ${AREngine_INCLUDE_DIRS}")
ENDIF(AREngine_FOUND)
ENDIF(WITH_ARENGINE AND ${ANDROID_NATIVE_API_LEVEL} GREATER 23)
IF(NOT Tango_FOUND)
SET(TANGO "//")
ENDIF(NOT Tango_FOUND)
IF(NOT ARCore_FOUND)
SET(ARCORE "//")
ENDIF(NOT ARCore_FOUND)
IF(NOT AREngine_FOUND)
SET(ARENGINE "//")
ENDIF(NOT AREngine_FOUND)
CONFIGURE_FILE(CameraAvailability.h.in ${CMAKE_CURRENT_SOURCE_DIR}/jni/CameraAvailability.h)
IF(DISABLE_LOG) IF(DISABLE_LOG)
ADD_DEFINITIONS(-DDISABLE_LOG) ADD_DEFINITIONS(-DDISABLE_LOG)
ENDIF(DISABLE_LOG) ENDIF(DISABLE_LOG)
IF(DEPTH_TEST)
ADD_DEFINITIONS(-DDEPTH_TEST)
ENDIF(DEPTH_TEST)
MESSAGE(STATUS "--------------------------------------------")
MESSAGE(STATUS "Android build info:")
MESSAGE(STATUS " DISABLE_LOG = ${DISABLE_LOG}")
MESSAGE(STATUS " DEPTH_TEST = ${DEPTH_TEST}")
IF(Tango_FOUND)
MESSAGE(STATUS " With Tango = YES")
ELSEIF(NOT WITH_TANGO)
MESSAGE(STATUS " With Tango = NO (WITH_TANGO=OFF)")
ELSE()
IF(${ANDROID_NATIVE_API_LEVEL} GREATER 23)
MESSAGE(STATUS " With Tango = NO (ANDROID_NATIVE_API_LEVEL should be <= 23)")
ELSE()
MESSAGE(STATUS " With Tango = NO (tango not found)")
ENDIF()
ENDIF()
IF(ARCore_FOUND)
MESSAGE(STATUS " With ARCore = YES")
ELSEIF(NOT WITH_ARCORE)
MESSAGE(STATUS " With ARCore = NO (WITH_ARCORE=OFF)")
ELSE()
IF(${ANDROID_NATIVE_API_LEVEL} LESS 23)
MESSAGE(STATUS " With ARCore = NO (ANDROID_NATIVE_API_LEVEL should be >= 23)")
ELSE()
MESSAGE(STATUS " With ARCore = NO (ARCore not found)")
ENDIF()
ENDIF()
IF(AREngine_FOUND)
MESSAGE(STATUS " With AREngine = YES")
ELSEIF(NOT WITH_ARENGINE)
MESSAGE(STATUS " With AREngine = NO (WITH_ARENGINE=OFF)")
ELSE()
IF(${ANDROID_NATIVE_API_LEVEL} LESS 24)
MESSAGE(STATUS " With AREngine = NO (ANDROID_NATIVE_API_LEVEL should be >= 24)")
ELSE()
MESSAGE(STATUS " With AREngine = NO (AREngine not found)")
ENDIF()
ENDIF()
MESSAGE(STATUS " ANDROID_NATIVE_API_LEVEL = ${ANDROID_NATIVE_API_LEVEL}")
MESSAGE(STATUS " ANDROID_COMPILER_FLAGS_RELEASE = ${ANDROID_COMPILER_FLAGS_RELEASE}")
MESSAGE(STATUS " ANDROID_TOOLCHAIN_PREFIX = ${ANDROID_TOOLCHAIN_PREFIX}")
MESSAGE(STATUS "DISABLE_LOG = ${DISABLE_LOG}")
IF(DISABLE_LOG) IF(DISABLE_LOG)
SET(ANDROID_DEBUGGABLE false) SET(ANDROID_DEBUGGABLE false)
@@ -29,7 +114,8 @@ endif()
configure_file( configure_file(
"${CMAKE_CURRENT_SOURCE_DIR}/AndroidManifest.xml.in" "${CMAKE_CURRENT_SOURCE_DIR}/AndroidManifest.xml.in"
"${CMAKE_CURRENT_SOURCE_DIR}/AndroidManifest.xml") "${CMAKE_CURRENT_SOURCE_DIR}/AndroidManifest.xml"
@ONLY)
configure_file( configure_file(
"${CMAKE_CURRENT_SOURCE_DIR}/AndroidManifest.xml" "${CMAKE_CURRENT_SOURCE_DIR}/AndroidManifest.xml"
@@ -1,41 +1,39 @@
/* /*
Copyright (c) 2010-2016, Mathieu Labbe - IntRoLab - Universite de Sherbrooke Copyright (c) 2010-2014, 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
modification, are permitted provided that the following conditions are met: modification, are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright * Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer. notice, this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright * Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution. documentation and/or other materials provided with the distribution.
* Neither the name of the Universite de Sherbrooke nor the * Neither the name of the Universite de Sherbrooke nor the
names of its contributors may be used to endorse or promote products names of its contributors may be used to endorse or promote products
derived from this software without specific prior written permission. derived from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 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 ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DISCLAIMED. IN NO EVENT SHALL UNIVERTY DE SHERBROOKE BE LIABLE FOR ANY
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 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 (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/ */
#ifndef RTABMAPGUIEXP_H #ifndef CAMERAAVAILABILITY_H_
#define RTABMAPGUIEXP_H #define CAMERAAVAILABILITY_H_
// This is auto-generated!
@TANGO@#define RTABMAP_TANGO
@ARCORE@#define RTABMAP_ARCORE
@ARENGINE@#define RTABMAP_ARENGINE
#endif /* CAMERAAVAILABILITY_H_ */
#if defined(_WIN32)
#if defined(rtabmap_gui_EXPORTS)
#define RTABMAPGUI_EXP __declspec( dllexport )
#else
#define RTABMAPGUI_EXP __declspec( dllimport )
#endif
#else
#define RTABMAPGUI_EXP
#endif
#endif // RTABMAPGUIEXP_H
+3 -3
View File
@@ -6,8 +6,8 @@
<copy todir="${native.libs.dir}/${android.abi}"> <copy todir="${native.libs.dir}/${android.abi}">
<fileset dir="${srcdir}/jni/third-party/lib" includes="*.so"/> <fileset dir="${srcdir}/jni/third-party/lib" includes="*.so"/>
</copy> </copy>
<copy todir="${native.libs.dir}"> <copy todir="${native.libs.dir}">
<fileset dir="${srcdir}/jni/third-party/lib" includes="${android.abi}/*.so"/> <fileset dir="${srcdir}/jni/third-party/lib" includes="${android.abi}/*.so"/>
</copy> </copy>
</target> </target>
</project> </project>
+1 -1
View File
@@ -1,7 +1,7 @@
<h3>Real-Time Appearance-Based Mapping</h3> <h3>Real-Time Appearance-Based Mapping</h3>
Version @RTABMAP_VERSION@<br> Version @RTABMAP_VERSION@<br>
Author: Mathieu Labb&eacute;<br> Author: Mathieu Labb&eacute;<br>
Copyright 2016-2017<br> Copyright 2016-2020<br>
IntRoLab - Universit&eacute; de Sherbrooke<br> IntRoLab - Universit&eacute; de Sherbrooke<br>
<b>http://introlab.github.io/rtabmap</b><br><br> <b>http://introlab.github.io/rtabmap</b><br><br>
+1
View File
@@ -0,0 +1 @@
CameraAvailability.h
+86 -9
View File
@@ -1,35 +1,29 @@
find_package(Tango REQUIRED)
SET(INCLUDE_DIRS SET(INCLUDE_DIRS
${CMAKE_CURRENT_SOURCE_DIR} ${CMAKE_CURRENT_SOURCE_DIR}
${CMAKE_CURRENT_SOURCE_DIR}/tango-gl/include ${CMAKE_CURRENT_SOURCE_DIR}/tango-gl/include
${CMAKE_CURRENT_SOURCE_DIR}/third-party/include ${CMAKE_CURRENT_SOURCE_DIR}/third-party/include
${PROJECT_BINARY_DIR}/corelib/include
${PROJECT_SOURCE_DIR}/corelib/include ${PROJECT_SOURCE_DIR}/corelib/include
${PROJECT_SOURCE_DIR}/utilite/include ${PROJECT_SOURCE_DIR}/utilite/include
${OpenCV_INCLUDE_DIRS} ${OpenCV_INCLUDE_DIRS}
${PCL_INCLUDE_DIRS} ${PCL_INCLUDE_DIRS}
${Tango_INCLUDE_DIRS}
"${ANDROID_NDK}/platforms/android-${ANDROID_NATIVE_API_LEVEL}/arch-${ANDROID_ARCH_NAME}/usr/include" "${ANDROID_NDK}/platforms/android-${ANDROID_NATIVE_API_LEVEL}/arch-${ANDROID_ARCH_NAME}/usr/include"
) )
SET(LIBRARIES SET(LIBRARIES
${OpenCV_LIBRARIES} ${OpenCV_LIBRARIES}
${PCL_LIBRARIES} ${PCL_LIBRARIES}
${Tango_LIBRARIES}
) )
add_definitions(${PCL_DEFINITIONS})
INCLUDE_DIRECTORIES(${INCLUDE_DIRS})
set(sources set(sources
jni_interface.cpp jni_interface.cpp
CameraTango.cpp CameraMobile.cpp
RTABMapApp.cpp RTABMapApp.cpp
scene.cpp scene.cpp
point_cloud_drawable.cpp point_cloud_drawable.cpp
graph_drawable.cpp graph_drawable.cpp
background_renderer.cc
tango-gl/axis.cpp tango-gl/axis.cpp
tango-gl/camera.cpp tango-gl/camera.cpp
tango-gl/conversions.cpp tango-gl/conversions.cpp
@@ -44,6 +38,82 @@ set(sources
tango-gl/util.cpp tango-gl/util.cpp
) )
IF(OPENMP_FOUND)
file(COPY ${OpenMP_CXX_LIBRARIES}
DESTINATION ${CMAKE_CURRENT_BINARY_DIR}/../libs/${ANDROID_NDK_ABI_NAME})
ENDIF(OPENMP_FOUND)
IF(Tango_FOUND)
SET(sources
${sources}
CameraTango.cpp
)
SET(INCLUDE_DIRS
${INCLUDE_DIRS}
${Tango_INCLUDE_DIRS}
)
SET(LIBRARIES
${LIBRARIES}
${Tango_LIBRARIES}
)
file(COPY ${Tango_support_LIBRARY}
DESTINATION ${CMAKE_CURRENT_BINARY_DIR}/../libs/${ANDROID_NDK_ABI_NAME})
ENDIF(Tango_FOUND)
IF(ARCore_FOUND)
SET(sources
${sources}
CameraARCore.cpp
)
SET(INCLUDE_DIRS
${INCLUDE_DIRS}
${ARCore_INCLUDE_DIRS}
)
SET(LIBRARIES
${LIBRARIES}
${ARCore_LIBRARIES}
)
file(COPY ${ARCore_c_LIBRARY}
DESTINATION ${CMAKE_CURRENT_BINARY_DIR}/../libs/${ANDROID_NDK_ABI_NAME})
file(COPY ${ARCore_jni_LIBRARY}
DESTINATION ${CMAKE_CURRENT_BINARY_DIR}/../libs/${ANDROID_NDK_ABI_NAME})
ENDIF(ARCore_FOUND)
IF(AREngine_FOUND)
SET(sources
${sources}
CameraAREngine.cpp
)
SET(INCLUDE_DIRS
${INCLUDE_DIRS}
${AREngine_INCLUDE_DIRS}
)
SET(LIBRARIES
${LIBRARIES}
${AREngine_LIBRARIES}
camera2ndk
mediandk
)
file(COPY ${AREngine_impl_LIBRARY}
DESTINATION ${CMAKE_CURRENT_BINARY_DIR}/../libs/${ANDROID_NDK_ABI_NAME})
file(COPY ${AREngine_jni_LIBRARY}
DESTINATION ${CMAKE_CURRENT_BINARY_DIR}/../libs/${ANDROID_NDK_ABI_NAME})
file(COPY ${AREngine_ndk_LIBRARY}
DESTINATION ${CMAKE_CURRENT_BINARY_DIR}/../libs/${ANDROID_NDK_ABI_NAME})
ENDIF(AREngine_FOUND)
add_definitions(${PCL_DEFINITIONS})
INCLUDE_DIRECTORIES(${INCLUDE_DIRS})
add_library(NativeRTABMap SHARED ${sources}) add_library(NativeRTABMap SHARED ${sources})
target_link_libraries(NativeRTABMap ${LIBRARIES} target_link_libraries(NativeRTABMap ${LIBRARIES}
android android
@@ -58,3 +128,10 @@ set_target_properties(NativeRTABMap PROPERTIES
LIBRARY_OUTPUT_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/../libs/${ANDROID_NDK_ABI_NAME}" LIBRARY_OUTPUT_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/../libs/${ANDROID_NDK_ABI_NAME}"
LIBRARY_OUTPUT_DIRECTORY_DEBUG "${CMAKE_CURRENT_BINARY_DIR}/../libs/${ANDROID_NDK_ABI_NAME}" LIBRARY_OUTPUT_DIRECTORY_DEBUG "${CMAKE_CURRENT_BINARY_DIR}/../libs/${ANDROID_NDK_ABI_NAME}"
LIBRARY_OUTPUT_DIRECTORY_RELEASE "${CMAKE_CURRENT_BINARY_DIR}/../libs/${ANDROID_NDK_ABI_NAME}") LIBRARY_OUTPUT_DIRECTORY_RELEASE "${CMAKE_CURRENT_BINARY_DIR}/../libs/${ANDROID_NDK_ABI_NAME}")
IF(ANDROID_NATIVE_API_LEVEL GREATER 22)
add_custom_command(TARGET NativeRTABMap POST_BUILD
COMMAND "${ANDROID_TOOLCHAIN_PREFIX}strip" -g -S -d --strip-debug --verbose
"${CMAKE_CURRENT_BINARY_DIR}/../libs/${ANDROID_NDK_ABI_NAME}/libNativeRTABMap.so"
COMMENT "Strip debug symbols done on final binary.")
ENDIF(ANDROID_NATIVE_API_LEVEL GREATER 22)
+704
View File
@@ -0,0 +1,704 @@
/*
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.
*/
#include "CameraARCore.h"
#include "util.h"
#include "rtabmap/utilite/ULogger.h"
#include "rtabmap/core/util3d_transforms.h"
#include "rtabmap/core/OdometryEvent.h"
#include "rtabmap/core/util2d.h"
namespace rtabmap {
//////////////////////////////
// CameraARCore
//////////////////////////////
CameraARCore::CameraARCore(void* env, void* context, void* activity, bool depthFromMotion, bool smoothing):
CameraMobile(smoothing),
env_(env),
context_(context),
activity_(activity),
arInstallRequested_(false),
depthFromMotion_(depthFromMotion)
{
}
CameraARCore::~CameraARCore() {
// Disconnect ARCore service
close();
}
struct CameraConfig {
int32_t width = 0;
int32_t height = 0;
std::string config_label;
ArCameraConfig* config = nullptr;
};
void getCameraConfigLowestAndHighestResolutions(
std::vector<CameraConfig> & camera_configs,
CameraConfig** lowest_resolution_config,
CameraConfig** highest_resolution_config) {
if (camera_configs.empty()) {
return;
}
int low_resolution_config_idx = 0;
int high_resolution_config_idx = 0;
int32_t smallest_height = camera_configs[0].height;
int32_t largest_height = camera_configs[0].height;
for (int i = 1; i < camera_configs.size(); ++i) {
int32_t image_height = camera_configs[i].height;
if (image_height < smallest_height) {
smallest_height = image_height;
low_resolution_config_idx = i;
} else if (image_height > largest_height) {
largest_height = image_height;
high_resolution_config_idx = i;
}
}
if (low_resolution_config_idx == high_resolution_config_idx) {
*lowest_resolution_config = &camera_configs[low_resolution_config_idx];
} else {
*lowest_resolution_config = &camera_configs[low_resolution_config_idx];
*highest_resolution_config = &camera_configs[high_resolution_config_idx];
}
}
void copyCameraConfig(
const ArSession* ar_session, const ArCameraConfigList* all_configs,
int index, int num_configs, CameraConfig* camera_config) {
if (camera_config != nullptr && index >= 0 && index < num_configs) {
ArCameraConfig_create(ar_session, &camera_config->config);
ArCameraConfigList_getItem(ar_session, all_configs, index,
camera_config->config);
ArCameraConfig_getImageDimensions(ar_session, camera_config->config,
&camera_config->width,
&camera_config->height);
camera_config->config_label = "(" + std::to_string(camera_config->width) +
"x" + std::to_string(camera_config->height) +
")";
}
}
void destroyCameraConfigs(std::vector<CameraConfig> & camera_configs) {
for (int i = 0; i < camera_configs.size(); ++i) {
if (camera_configs[i].config != nullptr) {
ArCameraConfig_destroy(camera_configs[i].config);
}
}
}
std::string CameraARCore::getSerial() const
{
return "ARCore";
}
bool CameraARCore::init(const std::string & calibrationFolder, const std::string & cameraName)
{
close();
UScopeMutex lock(arSessionMutex_);
ArInstallStatus install_status;
// If install was not yet requested, that means that we are resuming the
// activity first time because of explicit user interaction (such as
// launching the application)
bool user_requested_install = !arInstallRequested_;
// === ATTENTION! ATTENTION! ATTENTION! ===
// This method can and will fail in user-facing situations. Your
// application must handle these cases at least somewhat gracefully. See
// HelloAR Java sample code for reasonable behavior.
ArCoreApk_requestInstall(env_, activity_, user_requested_install, &install_status);
switch (install_status)
{
case AR_INSTALL_STATUS_INSTALLED:
break;
case AR_INSTALL_STATUS_INSTALL_REQUESTED:
arInstallRequested_ = true;
return false;
}
// === ATTENTION! ATTENTION! ATTENTION! ===
// This method can and will fail in user-facing situations. Your
// application must handle these cases at least somewhat gracefully. See
// HelloAR Java sample code for reasonable behavior.
UASSERT(ArSession_create(env_, context_, &arSession_) == AR_SUCCESS);
UASSERT(arSession_);
int32_t is_depth_supported = 0;
ArSession_isDepthModeSupported(arSession_, AR_DEPTH_MODE_AUTOMATIC, &is_depth_supported);
ArConfig_create(arSession_, &arConfig_);
UASSERT(arConfig_);
if (is_depth_supported!=0) {
ArConfig_setDepthMode(arSession_, arConfig_, AR_DEPTH_MODE_AUTOMATIC);
} else {
ArConfig_setDepthMode(arSession_, arConfig_, AR_DEPTH_MODE_DISABLED);
}
ArConfig_setFocusMode(arSession_, arConfig_, AR_FOCUS_MODE_FIXED);
UASSERT(ArSession_configure(arSession_, arConfig_) == AR_SUCCESS);
ArFrame_create(arSession_, &arFrame_);
UASSERT(arFrame_);
ArCameraIntrinsics_create(arSession_, &arCameraIntrinsics_);
UASSERT(arCameraIntrinsics_);
ArPose_create(arSession_, nullptr, &arPose_);
UASSERT(arPose_);
ArCameraConfigList* all_camera_configs = nullptr;
int32_t num_configs = 0;
ArCameraConfigList_create(arSession_, &all_camera_configs);
// Create filter first to get both 30 and 60 fps.
ArCameraConfigFilter* camera_config_filter = nullptr;
ArCameraConfigFilter_create(arSession_, &camera_config_filter);
ArCameraConfigFilter_setTargetFps(arSession_, camera_config_filter, AR_CAMERA_CONFIG_TARGET_FPS_30 | AR_CAMERA_CONFIG_TARGET_FPS_60);
ArSession_getSupportedCameraConfigsWithFilter(arSession_, camera_config_filter, all_camera_configs);
ArCameraConfigList_getSize(arSession_, all_camera_configs, &num_configs);
if (num_configs < 1) {
UERROR("No camera config found");
close();
return false;
}
std::vector<CameraConfig> camera_configs;
CameraConfig* cpu_low_resolution_camera_config_ptr = nullptr;
CameraConfig* cpu_high_resolution_camera_config_ptr = nullptr;
camera_configs.resize(num_configs);
for (int i = 0; i < num_configs; ++i) {
copyCameraConfig(arSession_, all_camera_configs, i, num_configs,
&camera_configs[i]);
}
// Determine the highest and lowest CPU resolutions.
cpu_low_resolution_camera_config_ptr = nullptr;
cpu_high_resolution_camera_config_ptr = nullptr;
getCameraConfigLowestAndHighestResolutions(
camera_configs,
&cpu_low_resolution_camera_config_ptr,
&cpu_high_resolution_camera_config_ptr);
// Cleanup the list obtained as it is safe to destroy the list as camera
// config instances were explicitly created and copied. Refer to the
// previous comment.
ArCameraConfigList_destroy(all_camera_configs);
ArSession_setCameraConfig(arSession_, cpu_low_resolution_camera_config_ptr->config);
/// Sets the behavior of @ref ArSession_update(). See
/// ::ArUpdateMode for available options.
ArConfig_setUpdateMode(arSession_, arConfig_, AR_UPDATE_MODE_BLOCKING);
deviceTColorCamera_ = opticalRotation;
if (ArSession_resume(arSession_) != ArStatus::AR_SUCCESS)
{
UERROR("Cannot resume camera!");
// In a rare case (such as another camera app launching) the camera may be
// given to a different app and so may not be available to this app. Handle
// this properly and recreate the session at the next iteration.
close();
return false;
}
return true;
}
void CameraARCore::close()
{
UScopeMutex lock(arSessionMutex_);
if(arSession_!= nullptr)
{
ArSession_destroy(arSession_);
}
arSession_ = nullptr;
if(arConfig_!= nullptr)
{
ArConfig_destroy(arConfig_);
}
arConfig_ = nullptr;
if (arFrame_ != nullptr)
{
ArFrame_destroy(arFrame_);
}
arFrame_ = nullptr;
if (arCameraIntrinsics_ != nullptr)
{
ArCameraIntrinsics_destroy(arCameraIntrinsics_);
}
arCameraIntrinsics_ = nullptr;
if (arPose_ != nullptr)
{
ArPose_destroy(arPose_);
}
arPose_ = nullptr;
CameraMobile::close();
}
LaserScan CameraARCore::scanFromPointCloudData(
const float * pointCloudData,
int points,
const Transform & pose,
const CameraModel & model,
const cv::Mat & rgb,
std::vector<cv::KeyPoint> * kpts,
std::vector<cv::Point3f> * kpts3D)
{
if(pointCloudData && points>0)
{
cv::Mat scanData(1, points, CV_32FC4);
float * ptr = scanData.ptr<float>();
for(unsigned int i=0;i<points; ++i)
{
cv::Point3f pt(pointCloudData[i*4], pointCloudData[i*4 + 1], pointCloudData[i*4 + 2]);
pt = util3d::transformPoint(pt, pose.inverse()*rtabmap_world_T_opengl_world);
ptr[i*4] = pt.x;
ptr[i*4 + 1] = pt.y;
ptr[i*4 + 2] = pt.z;
//get color from rgb image
cv::Point3f org= pt;
pt = util3d::transformPoint(pt, opticalRotationInv);
int u,v;
model.reproject(pt.x, pt.y, pt.z, u, v);
unsigned char r=255,g=255,b=255;
if(model.inFrame(u, v))
{
b=rgb.at<cv::Vec3b>(v,u).val[0];
g=rgb.at<cv::Vec3b>(v,u).val[1];
r=rgb.at<cv::Vec3b>(v,u).val[2];
if(kpts)
kpts->push_back(cv::KeyPoint(u,v,3));
if(kpts3D)
kpts3D->push_back(org);
}
*(int*)&ptr[i*4 + 3] = int(b) | (int(g) << 8) | (int(r) << 16);
//confidence
//*(int*)&ptr[i*4 + 3] = (int(pointCloudData[i*4 + 3] * 255.0f) << 8) | (int(255) << 16);
}
return LaserScan::backwardCompatibility(scanData, 0, 10, rtabmap::Transform::getIdentity());
}
return LaserScan();
}
void CameraARCore::setScreenRotationAndSize(ScreenRotation colorCameraToDisplayRotation, int width, int height)
{
CameraMobile::setScreenRotationAndSize(colorCameraToDisplayRotation, width, height);
if(arSession_)
{
int ret = static_cast<int>(colorCameraToDisplayRotation) + 1; // remove 90deg camera rotation
if (ret > 3) {
ret -= 4;
}
ArSession_setDisplayGeometry(arSession_, ret, width, height);
}
}
SensorData CameraARCore::captureImage(CameraInfo * info)
{
UScopeMutex lock(arSessionMutex_);
//LOGI("Capturing image...");
SensorData data;
if(!arSession_)
{
return data;
}
if(textureId_ == 0)
{
glGenTextures(1, &textureId_);
glBindTexture(GL_TEXTURE_EXTERNAL_OES, textureId_);
glTexParameteri(GL_TEXTURE_EXTERNAL_OES, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_EXTERNAL_OES, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_EXTERNAL_OES, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_EXTERNAL_OES, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
}
if(textureId_!=0)
ArSession_setCameraTextureName(arSession_, textureId_);
// Update session to get current frame and render camera background.
if (ArSession_update(arSession_, arFrame_) != AR_SUCCESS) {
LOGE("CameraARCore::captureImage() ArSession_update error");
return data;
}
// If display rotation changed (also includes view size change), we need to
// re-query the uv coordinates for the on-screen portion of the camera image.
int32_t geometry_changed = 0;
ArFrame_getDisplayGeometryChanged(arSession_, arFrame_, &geometry_changed);
if (geometry_changed != 0 || !uvs_initialized_) {
ArFrame_transformCoordinates2d(
arSession_, arFrame_, AR_COORDINATES_2D_OPENGL_NORMALIZED_DEVICE_COORDINATES,
BackgroundRenderer::kNumVertices, BackgroundRenderer_kVertices, AR_COORDINATES_2D_TEXTURE_NORMALIZED,
transformed_uvs_);
UASSERT(transformed_uvs_);
uvs_initialized_ = true;
}
ArCamera* ar_camera;
ArFrame_acquireCamera(arSession_, arFrame_, &ar_camera);
ArCamera_getViewMatrix(arSession_, ar_camera, glm::value_ptr(viewMatrix_));
ArCamera_getProjectionMatrix(arSession_, ar_camera,
/*near=*/0.1f, /*far=*/100.f,
glm::value_ptr(projectionMatrix_));
// adjust origin
if(!getOriginOffset().isNull())
{
viewMatrix_ = glm::inverse(rtabmap::glmFromTransform(rtabmap::opengl_world_T_rtabmap_world * getOriginOffset() *rtabmap::rtabmap_world_T_opengl_world)*glm::inverse(viewMatrix_));
}
ArTrackingState camera_tracking_state;
ArCamera_getTrackingState(arSession_, ar_camera, &camera_tracking_state);
Transform pose;
CameraModel model;
if(camera_tracking_state == AR_TRACKING_STATE_TRACKING)
{
// pose in OpenGL coordinates
float pose_raw[7];
ArCamera_getPose(arSession_, ar_camera, arPose_);
ArPose_getPoseRaw(arSession_, arPose_, pose_raw);
pose = Transform(pose_raw[4], pose_raw[5], pose_raw[6], pose_raw[0], pose_raw[1], pose_raw[2], pose_raw[3]);
pose = rtabmap::rtabmap_world_T_opengl_world * pose * rtabmap::opengl_world_T_rtabmap_world;
Transform poseArCore = pose;
if(pose.isNull())
{
LOGE("CameraARCore: Pose is null");
}
else
{
this->poseReceived(pose);
// adjust origin
if(!getOriginOffset().isNull())
{
pose = getOriginOffset() * pose;
}
info->odomPose = pose;
}
// Get calibration parameters
float fx,fy, cx, cy;
int32_t width, height;
ArCamera_getImageIntrinsics(arSession_, ar_camera, arCameraIntrinsics_);
ArCameraIntrinsics_getFocalLength(arSession_, arCameraIntrinsics_, &fx, &fy);
ArCameraIntrinsics_getPrincipalPoint(arSession_, arCameraIntrinsics_, &cx, &cy);
ArCameraIntrinsics_getImageDimensions(arSession_, arCameraIntrinsics_, &width, &height);
#ifndef DISABLE_LOG
LOGI("%f %f %f %f %d %d", fx, fy, cx, cy, width, height);
#endif
if(fx > 0 && fy > 0 && width > 0 && height > 0 && cx > 0 && cy > 0)
{
model = CameraModel(fx, fy, cx, cy, deviceTColorCamera_, 0, cv::Size(width, height));
ArPointCloud * pointCloud = nullptr;
ArFrame_acquirePointCloud(arSession_, arFrame_, &pointCloud);
int32_t is_depth_supported = 0;
ArSession_isDepthModeSupported(arSession_, AR_DEPTH_MODE_AUTOMATIC, &is_depth_supported);
ArImage * image = nullptr;
ArStatus status = ArFrame_acquireCameraImage(arSession_, arFrame_, &image);
if(status == AR_SUCCESS)
{
if(is_depth_supported)
{
LOGD("Acquire depth image!");
ArImage * depthImage = nullptr;
ArFrame_acquireDepthImage(arSession_, arFrame_, &depthImage);
ArImageFormat format;
ArImage_getFormat(arSession_, depthImage, &format);
if(format == AR_IMAGE_FORMAT_DEPTH16)
{
LOGD("Depth format detected!");
int planeCount;
ArImage_getNumberOfPlanes(arSession_, depthImage, &planeCount);
LOGD("planeCount=%d", planeCount);
UASSERT_MSG(planeCount == 1, uFormat("Error: getNumberOfPlanes() planceCount = %d", planeCount).c_str());
const uint8_t *data = nullptr;
int len = 0;
int stride;
int depth_width;
int depth_height;
ArImage_getWidth(arSession_, depthImage, &depth_width);
ArImage_getHeight(arSession_, depthImage, &depth_height);
ArImage_getPlaneRowStride(arSession_, depthImage, 0, &stride);
ArImage_getPlaneData(arSession_, depthImage, 0, &data, &len);
LOGD("width=%d, height=%d, bytes=%d stride=%d", depth_width, depth_height, len, stride);
cv::Mat occlusionImage = cv::Mat(depth_height, depth_width, CV_16UC1, (void*)data).clone();
float scaleX = (float)depth_width / (float)width;
float scaleY = (float)depth_height / (float)height;
CameraModel occlusionModel(fx*scaleX, fy*scaleY, cx*scaleX, cy*scaleY, pose*deviceTColorCamera_, 0, cv::Size(depth_width, depth_height));
this->setOcclusionImage(occlusionImage, occlusionModel);
}
ArImage_release(depthImage);
}
int64_t timestamp_ns;
ArImageFormat format;
ArImage_getTimestamp(arSession_, image, &timestamp_ns);
ArImage_getFormat(arSession_, image, &format);
if(format == AR_IMAGE_FORMAT_YUV_420_888)
{
#ifndef DISABLE_LOG
int32_t num_planes;
ArImage_getNumberOfPlanes(arSession_, image, &num_planes);
for(int i=0;i<num_planes; ++i)
{
int32_t pixel_stride;
int32_t row_stride;
ArImage_getPlanePixelStride(arSession_, image, i, &pixel_stride);
ArImage_getPlaneRowStride(arSession_, image, i, &row_stride);
LOGI("Plane %d/%d: pixel stride=%d, row stride=%d", i+1, num_planes, pixel_stride, row_stride);
}
#endif
const uint8_t * plane_data;
const uint8_t * plane_uv_data;
int32_t data_length;
ArImage_getPlaneData(arSession_, image, 0, &plane_data, &data_length);
int32_t uv_data_length;
ArImage_getPlaneData(arSession_, image, 2, &plane_uv_data, &uv_data_length);
if(plane_data != nullptr && data_length == height*width)
{
double stamp = double(timestamp_ns)/10e8;
#ifndef DISABLE_LOG
LOGI("data_length=%d stamp=%f", data_length, stamp);
#endif
cv::Mat rgb;
if((long)plane_uv_data-(long)plane_data != data_length)
{
// The uv-plane is not concatenated to y plane in memory, so concatenate them
cv::Mat yuv(height+height/2, width, CV_8UC1);
memcpy(yuv.data, plane_data, data_length);
memcpy(yuv.data+data_length, plane_uv_data, height/2*width);
cv::cvtColor(yuv, rgb, cv::COLOR_YUV2BGR_NV21);
}
else
{
cv::cvtColor(cv::Mat(height+height/2, width, CV_8UC1, (void*)plane_data), rgb, cv::COLOR_YUV2BGR_NV21);
}
std::vector<cv::KeyPoint> kpts;
std::vector<cv::Point3f> kpts3;
LaserScan scan;
if(pointCloud)
{
int32_t points = 0;
ArPointCloud_getNumberOfPoints(arSession_, pointCloud, &points);
const float * pointCloudData = 0;
ArPointCloud_getData(arSession_, pointCloud, &pointCloudData);
#ifndef DISABLE_LOG
LOGI("pointCloudData=%d size=%d", pointCloudData?1:0, points);
#endif
if(pointCloudData && points>0)
{
scan = scanFromPointCloudData(pointCloudData, points, poseArCore, model, rgb, &kpts, &kpts3);
}
}
else
{
LOGI("pointCloud empty");
}
data = SensorData(scan, rgb, depthFromMotion_?getOcclusionImage():cv::Mat(), model, 0, stamp);
data.setFeatures(kpts, kpts3, cv::Mat());
}
}
else
{
LOGE("CameraARCore: cannot convert image format %d", format);
}
}
else
{
LOGE("CameraARCore: failed to get rgb image (status=%d)", (int)status);
}
ArImage_release(image);
ArPointCloud_release(pointCloud);
}
}
ArCamera_release(ar_camera);
return data;
}
void CameraARCore::capturePoseOnly()
{
UScopeMutex lock(arSessionMutex_);
//LOGI("Capturing image...");
if(!arSession_)
{
return;
}
if(textureId_ != 0)
{
glBindTexture(GL_TEXTURE_EXTERNAL_OES, textureId_);
glTexParameteri(GL_TEXTURE_EXTERNAL_OES, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_EXTERNAL_OES, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_EXTERNAL_OES, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_EXTERNAL_OES, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
ArSession_setCameraTextureName(arSession_, textureId_);
}
// Update session to get current frame and render camera background.
if (ArSession_update(arSession_, arFrame_) != AR_SUCCESS) {
LOGE("CameraARCore::capturePoseOnly() ArSession_update error");
return;
}
// If display rotation changed (also includes view size change), we need to
// re-query the uv coordinates for the on-screen portion of the camera image.
int32_t geometry_changed = 0;
ArFrame_getDisplayGeometryChanged(arSession_, arFrame_, &geometry_changed);
if (geometry_changed != 0 || !uvs_initialized_) {
ArFrame_transformCoordinates2d(
arSession_, arFrame_, AR_COORDINATES_2D_OPENGL_NORMALIZED_DEVICE_COORDINATES,
BackgroundRenderer::kNumVertices, BackgroundRenderer_kVertices, AR_COORDINATES_2D_TEXTURE_NORMALIZED,
transformed_uvs_);
UASSERT(transformed_uvs_);
uvs_initialized_ = true;
}
ArCamera* ar_camera;
ArFrame_acquireCamera(arSession_, arFrame_, &ar_camera);
ArCamera_getViewMatrix(arSession_, ar_camera, glm::value_ptr(viewMatrix_));
ArCamera_getProjectionMatrix(arSession_, ar_camera,
/*near=*/0.1f, /*far=*/100.f,
glm::value_ptr(projectionMatrix_));
// adjust origin
if(!getOriginOffset().isNull())
{
viewMatrix_ = glm::inverse(rtabmap::glmFromTransform(rtabmap::opengl_world_T_rtabmap_world * getOriginOffset() *rtabmap::rtabmap_world_T_opengl_world)*glm::inverse(viewMatrix_));
}
ArTrackingState camera_tracking_state;
ArCamera_getTrackingState(arSession_, ar_camera, &camera_tracking_state);
Transform pose;
CameraModel model;
if(camera_tracking_state == AR_TRACKING_STATE_TRACKING)
{
// pose in OpenGL coordinates
float pose_raw[7];
ArCamera_getPose(arSession_, ar_camera, arPose_);
ArPose_getPoseRaw(arSession_, arPose_, pose_raw);
pose = Transform(pose_raw[4], pose_raw[5], pose_raw[6], pose_raw[0], pose_raw[1], pose_raw[2], pose_raw[3]);
if(!pose.isNull())
{
pose = rtabmap::rtabmap_world_T_opengl_world * pose * rtabmap::opengl_world_T_rtabmap_world;
this->poseReceived(pose);
if(!getOriginOffset().isNull())
{
pose = getOriginOffset() * pose;
}
}
int32_t is_depth_supported = 0;
ArSession_isDepthModeSupported(arSession_, AR_DEPTH_MODE_AUTOMATIC, &is_depth_supported);
if(is_depth_supported)
{
LOGD("Acquire depth image!");
ArImage * depthImage = nullptr;
ArFrame_acquireDepthImage(arSession_, arFrame_, &depthImage);
ArImageFormat format;
ArImage_getFormat(arSession_, depthImage, &format);
if(format == AR_IMAGE_FORMAT_DEPTH16)
{
LOGD("Depth format detected!");
int planeCount;
ArImage_getNumberOfPlanes(arSession_, depthImage, &planeCount);
LOGD("planeCount=%d", planeCount);
UASSERT_MSG(planeCount == 1, uFormat("Error: getNumberOfPlanes() planceCount = %d", planeCount).c_str());
const uint8_t *data = nullptr;
int len = 0;
int stride;
int width;
int height;
ArImage_getWidth(arSession_, depthImage, &width);
ArImage_getHeight(arSession_, depthImage, &height);
ArImage_getPlaneRowStride(arSession_, depthImage, 0, &stride);
ArImage_getPlaneData(arSession_, depthImage, 0, &data, &len);
LOGD("width=%d, height=%d, bytes=%d stride=%d", width, height, len, stride);
cv::Mat occlusionImage = cv::Mat(height, width, CV_16UC1, (void*)data).clone();
float fx,fy, cx, cy;
int32_t rgb_width, rgb_height;
ArCamera_getImageIntrinsics(arSession_, ar_camera, arCameraIntrinsics_);
ArCameraIntrinsics_getFocalLength(arSession_, arCameraIntrinsics_, &fx, &fy);
ArCameraIntrinsics_getPrincipalPoint(arSession_, arCameraIntrinsics_, &cx, &cy);
ArCameraIntrinsics_getImageDimensions(arSession_, arCameraIntrinsics_, &rgb_width, &rgb_height);
float scaleX = (float)width / (float)rgb_width;
float scaleY = (float)height / (float)rgb_height;
CameraModel occlusionModel(fx*scaleX, fy*scaleY, cx*scaleX, cy*scaleY, pose*deviceTColorCamera_, 0, cv::Size(width, height));
this->setOcclusionImage(occlusionImage, occlusionModel);
}
ArImage_release(depthImage);
}
}
ArCamera_release(ar_camera);
}
} /* namespace rtabmap */
+103
View File
@@ -0,0 +1,103 @@
/*
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 CAMERAARCORE_H_
#define CAMERAARCORE_H_
#include "CameraMobile.h"
#include <rtabmap/core/Camera.h>
#include <rtabmap/core/GeodeticCoords.h>
#include <rtabmap/utilite/UMutex.h>
#include <rtabmap/utilite/USemaphore.h>
#include <rtabmap/utilite/UEventsSender.h>
#include <rtabmap/utilite/UThread.h>
#include <rtabmap/utilite/UEvent.h>
#include <rtabmap/utilite/UTimer.h>
#include <boost/thread/mutex.hpp>
#include <background_renderer.h>
#include <arcore_c_api.h>
#include <camera/NdkCameraDevice.h>
#include <camera/NdkCameraManager.h>
#include <media/NdkImageReader.h>
#include <android/native_window.h>
namespace rtabmap {
class CameraARCore : public CameraMobile {
public:
static LaserScan scanFromPointCloudData(
const float * pointCloudData,
int points,
const Transform & pose,
const CameraModel & model,
const cv::Mat & rgb,
std::vector<cv::KeyPoint> * kpts = 0,
std::vector<cv::Point3f> * kpts3D = 0);
public:
CameraARCore(void* env, void* context, void* activity, bool depthFromMotion = false, bool smoothing = false);
virtual ~CameraARCore();
bool uvsInitialized() const {return uvs_initialized_;}
const float* uvsTransformed() const {return transformed_uvs_;}
void getVPMatrices(glm::mat4 & view, glm::mat4 & projection) const {view=viewMatrix_; projection=projectionMatrix_;}
virtual void setScreenRotationAndSize(ScreenRotation colorCameraToDisplayRotation, int width, int height);
virtual bool init(const std::string & calibrationFolder = ".", const std::string & cameraName = "");
void setupGL();
virtual void close(); // close Tango connection
virtual std::string getSerial() const;
GLuint getTextureId() const {return textureId_;}
void imageCallback(AImageReader *reader);
protected:
virtual SensorData captureImage(CameraInfo * info = 0); // should be called in opengl thread
virtual void capturePoseOnly();
private:
rtabmap::Transform getPoseAtTimestamp(double timestamp);
private:
void * env_;
void * context_;
void * activity_;
ArSession* arSession_ = nullptr;
ArConfig* arConfig_ = nullptr;
ArFrame* arFrame_ = nullptr;
ArCameraIntrinsics *arCameraIntrinsics_ = nullptr;
ArPose * arPose_ = nullptr;
bool arInstallRequested_;
UMutex arSessionMutex_;
bool depthFromMotion_;
};
} /* namespace rtabmap */
#endif /* CAMERAARCORE_H_ */
+356
View File
@@ -0,0 +1,356 @@
/*
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.
*/
#include "CameraAREngine.h"
#include "util.h"
#include "rtabmap/utilite/ULogger.h"
#include "rtabmap/core/util3d_transforms.h"
#include "rtabmap/core/OdometryEvent.h"
#include "rtabmap/core/util2d.h"
#include <media/NdkImage.h>
namespace rtabmap {
//////////////////////////////
// CameraAREngine
//////////////////////////////
CameraAREngine::CameraAREngine(void* env, void* context, void* activity, bool smoothing):
CameraMobile(smoothing),
env_(env),
context_(context),
activity_(activity),
arInstallRequested_(false)
{
glGenTextures(1, &textureId_);
}
CameraAREngine::~CameraAREngine() {
// Disconnect ARCore service
close();
glDeleteTextures(1, &textureId_);
}
std::string CameraAREngine::getSerial() const
{
return "AREngine";
}
bool CameraAREngine::init(const std::string & calibrationFolder, const std::string & cameraName)
{
close();
UScopeMutex lock(arSessionMutex_);
HwArInstallStatus install_status;
// If install was not yet requested, that means that we are resuming the
// activity first time because of explicit user interaction (such as
// launching the application)
bool user_requested_install = !arInstallRequested_;
// === ATTENTION! ATTENTION! ATTENTION! ===
// This method can and will fail in user-facing situations. Your
// application must handle these cases at least somewhat gracefully. See
// HelloAR Java sample code for reasonable behavior.
HwArEnginesApk_requestInstall(env_, activity_, user_requested_install, &install_status);
switch (install_status)
{
case HWAR_INSTALL_STATUS_INSTALLED:
break;
case HWAR_INSTALL_STATUS_INSTALL_REQUESTED:
arInstallRequested_ = true;
return false;
}
// === ATTENTION! ATTENTION! ATTENTION! ===
// This method can and will fail in user-facing situations. Your
// application must handle these cases at least somewhat gracefully. See
// HelloAR Java sample code for reasonable behavior.
UASSERT(HwArSession_create(env_, context_, &arSession_) == HWAR_SUCCESS);
UASSERT(arSession_);
HwArConfig_create(arSession_, &arConfig_);
UASSERT(arConfig_);
HwArConfig_setFocusMode(arSession_, arConfig_, HWAR_FOCUS_MODE_FIXED);
UASSERT(HwArSession_configure(arSession_, arConfig_) == HWAR_SUCCESS);
HwArFrame_create(arSession_, &arFrame_);
UASSERT(arFrame_);
HwArCameraIntrinsics_create(arSession_, &arCameraIntrinsics_); // May fail?!
//UASSERT(arCameraIntrinsics_);
HwArPose_create(arSession_, nullptr, &arPose_);
UASSERT(arPose_);
/// Sets the behavior of @ref ArSession_update(). See
/// ::ArUpdateMode for available options.
HwArConfig_setUpdateMode(arSession_, arConfig_, HWAR_UPDATE_MODE_BLOCKING);
deviceTColorCamera_ = opticalRotation;
// Required as ArSession_update does some off-screen OpenGL stuff...
HwArSession_setCameraTextureName(arSession_, textureId_);
if (HwArSession_resume(arSession_) != HWAR_SUCCESS)
{
UERROR("Cannot resume camera!");
// In a rare case (such as another camera app launching) the camera may be
// given to a different app and so may not be available to this app. Handle
// this properly and recreate the session at the next iteration.
close();
return false;
}
return true;
}
void CameraAREngine::close()
{
UScopeMutex lock(arSessionMutex_);
if (arCameraIntrinsics_ != nullptr)
{
HwArCameraIntrinsics_destroy(arSession_, arCameraIntrinsics_);
}
arCameraIntrinsics_ = nullptr;
if(arSession_!= nullptr)
{
HwArSession_destroy(arSession_);
}
arSession_ = nullptr;
if(arConfig_!= nullptr)
{
HwArConfig_destroy(arConfig_);
}
arConfig_ = nullptr;
if (arFrame_ != nullptr)
{
HwArFrame_destroy(arFrame_);
}
arFrame_ = nullptr;
if (arPose_ != nullptr)
{
HwArPose_destroy(arPose_);
}
arPose_ = nullptr;
CameraMobile::close();
}
SensorData CameraAREngine::captureImage(CameraInfo * info)
{
UScopeMutex lock(arSessionMutex_);
//LOGI("Capturing image...");
SensorData data;
if(!arSession_)
{
return data;
}
// Update session to get current frame and render camera background.
if (HwArSession_update(arSession_, arFrame_) != HWAR_SUCCESS) {
LOGE("CameraAREngine::captureImage() ArSession_update error");
return data;
}
HwArCamera* ar_camera;
HwArFrame_acquireCamera(arSession_, arFrame_, &ar_camera);
HwArTrackingState camera_tracking_state;
HwArCamera_getTrackingState(arSession_, ar_camera, &camera_tracking_state);
Transform pose;
if(camera_tracking_state == HWAR_TRACKING_STATE_TRACKING)
{
// pose in OpenGL coordinates
float pose_raw[7];
HwArCamera_getPose(arSession_, ar_camera, arPose_);
HwArPose_getPoseRaw(arSession_, arPose_, pose_raw);
pose = Transform(pose_raw[4], pose_raw[5], pose_raw[6], pose_raw[0], pose_raw[1], pose_raw[2], pose_raw[3]);
// Get calibration parameters
// FIXME: Hard-coded as getting intrinsics with the api fails
float fx=492.689667,fy=492.606201, cx=323.594849, cy=234.659744;
int32_t camWidth=640, camHeight=480;
//HwArCamera_getImageIntrinsics(arSession_, ar_camera, arCameraIntrinsics_);
//HwArCameraIntrinsics_getFocalLength(arSession_, arCameraIntrinsics_, &fx, &fy);
//HwArCameraIntrinsics_getPrincipalPoint(arSession_, arCameraIntrinsics_, &cx, &cy);
//HwArCameraIntrinsics_getImageDimensions(arSession_, arCameraIntrinsics_, &camWidth, &camHeight);
LOGI("%f %f %f %f %d %d", fx, fy, cx, cy, camWidth, camHeight);
if(fx > 0 && fy > 0 && camWidth > 0 && camHeight > 0 && cx > 0 && cy > 0)
{
//ArPointCloud * point_cloud;
//ArFrame_acquirePointCloud(ar_session_, ar_frame_, &point_cloud);
HwArImage * image = nullptr;
HwArImage * depthImage = nullptr;
HwArStatus statusRgb = HwArFrame_acquireCameraImage(arSession_, arFrame_, &image);
HwArStatus statusDepth = HwArFrame_acquireDepthImage(arSession_, arFrame_, &depthImage);
if(statusRgb == HWAR_SUCCESS && statusDepth == HWAR_SUCCESS)
{
int64_t timestamp_ns;
HwArFrame_getTimestamp(arSession_, arFrame_, &timestamp_ns);
int planeCount;
uint8_t *imageData = nullptr;
int len = 0;
int stride;
int width;
int height;
const AImage* ndkImageRGB;
HwArImage_getNdkImage(image, &ndkImageRGB);
AImage_getNumberOfPlanes(ndkImageRGB, &planeCount);
AImage_getWidth(ndkImageRGB, &width);
AImage_getHeight(ndkImageRGB, &height);
AImage_getPlaneRowStride(ndkImageRGB, 0, &stride);
AImage_getPlaneData(ndkImageRGB, 0, &imageData, &len);
LOGI("RGB: width=%d, height=%d, bytes=%d stride=%d planeCount=%d", width, height, len, stride, planeCount);
cv::Mat outputRGB;
if(imageData != nullptr && len>0)
{
cv::cvtColor(cv::Mat(height+height/2, width, CV_8UC1, (void*)imageData), outputRGB, cv::COLOR_YUV2BGR_NV21);
}
//Depth
const AImage* ndkImageDepth;
HwArImage_getNdkImage(depthImage, &ndkImageDepth);
AImage_getNumberOfPlanes(ndkImageDepth, &planeCount);
AImage_getWidth(ndkImageDepth, &width);
AImage_getHeight(ndkImageDepth, &height);
AImage_getPlaneRowStride(ndkImageDepth, 0, &stride);
AImage_getPlaneData(ndkImageDepth, 0, &imageData, &len);
LOGI("Depth: width=%d, height=%d, bytes=%d stride=%d planeCount=%d", width, height, len, stride, planeCount);
cv::Mat outputDepth(height, width, CV_16UC1);
uint16_t *dataShort = (uint16_t *)imageData;
for (int y = 0; y < outputDepth.rows; ++y)
{
for (int x = 0; x < outputDepth.cols; ++x)
{
uint16_t depthSample = dataShort[y*outputDepth.cols + x];
uint16_t depthRange = (depthSample & 0x1FFF); // first 3 bits are confidence
outputDepth.at<uint16_t>(y,x) = depthRange;
}
}
if(!outputRGB.empty() && !outputDepth.empty())
{
double stamp = double(timestamp_ns)/10e8;
CameraModel model = CameraModel(fx, fy, cx, cy, deviceTColorCamera_, 0, cv::Size(camWidth, camHeight));
data = SensorData(outputRGB, outputDepth, model, 0, stamp);
}
}
else
{
LOGE("CameraAREngine: failed to get rgb image (status=%d %d)", (int)statusRgb, (int)statusDepth);
}
HwArImage_release(image);
HwArImage_release(depthImage);
}
else
{
LOGE("Invalid intrinsics!");
}
}
HwArCamera_release(ar_camera);
if(pose.isNull())
{
LOGE("CameraAREngine: Pose is null");
}
else
{
pose = rtabmap::rtabmap_world_T_opengl_world * pose * rtabmap::opengl_world_T_rtabmap_world;
this->poseReceived(pose);
// adjust origin
if(!getOriginOffset().isNull())
{
pose = getOriginOffset() * pose;
}
info->odomPose = pose;
}
return data;
}
void CameraAREngine::capturePoseOnly()
{
UScopeMutex lock(arSessionMutex_);
//LOGI("Capturing image...");
SensorData data;
if(!arSession_)
{
return;
}
// Update session to get current frame and render camera background.
if (HwArSession_update(arSession_, arFrame_) != HWAR_SUCCESS) {
LOGE("CameraARCore::captureImage() ArSession_update error");
return;
}
HwArCamera* ar_camera;
HwArFrame_acquireCamera(arSession_, arFrame_, &ar_camera);
HwArTrackingState camera_tracking_state;
HwArCamera_getTrackingState(arSession_, ar_camera, &camera_tracking_state);
Transform pose;
CameraModel model;
if(camera_tracking_state == HWAR_TRACKING_STATE_TRACKING)
{
// pose in OpenGL coordinates
float pose_raw[7];
HwArCamera_getPose(arSession_, ar_camera, arPose_);
HwArPose_getPoseRaw(arSession_, arPose_, pose_raw);
pose = Transform(pose_raw[4], pose_raw[5], pose_raw[6], pose_raw[0], pose_raw[1], pose_raw[2], pose_raw[3]);
if(!pose.isNull())
{
pose = rtabmap::rtabmap_world_T_opengl_world * pose * rtabmap::opengl_world_T_rtabmap_world;
this->poseReceived(pose);
}
}
HwArCamera_release(ar_camera);
}
} /* namespace rtabmap */
+78
View File
@@ -0,0 +1,78 @@
/*
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 CAMERAARENGINE_H_
#define CAMERAARENGINE_H_
#include "CameraMobile.h"
#include <rtabmap/core/Camera.h>
#include <rtabmap/core/GeodeticCoords.h>
#include <rtabmap/utilite/UMutex.h>
#include <rtabmap/utilite/USemaphore.h>
#include <rtabmap/utilite/UEventsSender.h>
#include <rtabmap/utilite/UThread.h>
#include <rtabmap/utilite/UEvent.h>
#include <rtabmap/utilite/UTimer.h>
#include <boost/thread/mutex.hpp>
#include <huawei_arengine_interface.h>
namespace rtabmap {
class CameraAREngine : public CameraMobile {
public:
CameraAREngine(void* env, void* context, void* activity, bool smoothing = false);
virtual ~CameraAREngine();
virtual bool init(const std::string & calibrationFolder = ".", const std::string & cameraName = "");
virtual void close(); // close Tango connection
virtual std::string getSerial() const;
protected:
virtual SensorData captureImage(CameraInfo * info = 0);
virtual void capturePoseOnly();
private:
rtabmap::Transform getPoseAtTimestamp(double timestamp);
private:
void * env_;
void * context_;
void * activity_;
HwArSession* arSession_ = nullptr;
HwArConfig* arConfig_ = nullptr;
HwArFrame* arFrame_ = nullptr;
HwArCameraIntrinsics *arCameraIntrinsics_ = nullptr;
HwArPose * arPose_ = nullptr;
bool arInstallRequested_;
GLuint textureId_;
UMutex arSessionMutex_;
};
} /* namespace rtabmap */
#endif /* CAMERAARENGINE_H_ */
+463
View File
@@ -0,0 +1,463 @@
/*
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.
*/
#include "CameraMobile.h"
#include "util.h"
#include "rtabmap/utilite/ULogger.h"
#include "rtabmap/core/util3d_transforms.h"
#include "rtabmap/core/OdometryEvent.h"
#include "rtabmap/core/util2d.h"
#include <glm/gtx/transform.hpp>
namespace rtabmap {
#define nullptr 0
//////////////////////////////
// CameraMobile
//////////////////////////////
const float CameraMobile::bilateralFilteringSigmaS = 2.0f;
const float CameraMobile::bilateralFilteringSigmaR = 0.075f;
const rtabmap::Transform CameraMobile::opticalRotation = Transform(
0.0f, 0.0f, 1.0f, 0.0f,
-1.0f, 0.0f, 0.0f, 0.0f,
0.0f, -1.0f, 0.0f, 0.0f);
const rtabmap::Transform CameraMobile::opticalRotationInv = Transform(
0.0f, -1.0f, 0.0f, 0.0f,
0.0f, 0.0f, -1.0f, 0.0f,
1.0f, 0.0f, 0.0f, 0.0f);
CameraMobile::CameraMobile(bool smoothing) :
Camera(10),
deviceTColorCamera_(Transform::getIdentity()),
spinOncePreviousStamp_(0.0),
textureId_(0),
uvs_initialized_(false),
previousStamp_(0.0),
stampEpochOffset_(0.0),
smoothing_(smoothing),
colorCameraToDisplayRotation_(ROTATION_0),
originUpdate_(false)
{
}
CameraMobile::~CameraMobile() {
// Disconnect camera service
close();
}
bool CameraMobile::init(const std::string &, const std::string &)
{
deviceTColorCamera_ = opticalRotation;
return true;
}
void CameraMobile::close()
{
previousPose_.setNull();
previousStamp_ = 0.0;
lastKnownGPS_ = GPS();
lastEnvSensors_.clear();
originOffset_ = Transform();
originUpdate_ = false;
pose_ = Transform();
data_ = SensorData();
if(textureId_ != 0)
{
glDeleteTextures(1, &textureId_);
textureId_ = 0;
}
}
void CameraMobile::resetOrigin()
{
previousPose_.setNull();
previousStamp_ = 0.0;
lastKnownGPS_ = GPS();
lastEnvSensors_.clear();
pose_ = Transform();
data_ = SensorData();
originUpdate_ = true;
}
void CameraMobile::poseReceived(const Transform & pose)
{
if(!pose.isNull())
{
// send pose of the camera (without optical rotation)
Transform p = pose*deviceTColorCamera_;
if(originUpdate_)
{
originOffset_ = p.translation().inverse();
originUpdate_ = false;
}
if(!originOffset_.isNull())
{
this->post(new PoseEvent(originOffset_*p));
}
else
{
this->post(new PoseEvent(p));
}
}
}
bool CameraMobile::isCalibrated() const
{
return model_.isValidForProjection();
}
void CameraMobile::setGPS(const GPS & gps)
{
lastKnownGPS_ = gps;
}
void CameraMobile::setData(const SensorData & data, const Transform & pose, const glm::mat4 & viewMatrix, const glm::mat4 & projectionMatrix, const float * texCoord)
{
LOGD("CameraMobile::setData pose=%s stamp=%f", pose.prettyPrint().c_str(), data.stamp());
data_ = data;
pose_ = pose;
viewMatrix_ = viewMatrix;
projectionMatrix_ = projectionMatrix;
// adjust origin
if(!originOffset_.isNull())
{
pose_ = originOffset_ * pose_;
viewMatrix_ = glm::inverse(rtabmap::glmFromTransform(rtabmap::opengl_world_T_rtabmap_world * originOffset_ *rtabmap::rtabmap_world_T_opengl_world)*glm::inverse(viewMatrix_));
}
if(textureId_ == 0)
{
glGenTextures(1, &textureId_);
}
if(texCoord)
{
memcpy(transformed_uvs_, texCoord, 8*sizeof(float));
uvs_initialized_ = true;
}
LOGD("CameraMobile::setData textureId_=%d", (int)textureId_);
if(textureId_ != 0 && texCoord != 0)
{
cv::Mat rgbImage;
cv::cvtColor(data.imageRaw(), rgbImage, cv::COLOR_BGR2RGBA);
glBindTexture(GL_TEXTURE_2D, textureId_);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
glPixelStorei(GL_UNPACK_ALIGNMENT, 4);
//glPixelStorei(GL_UNPACK_ROW_LENGTH, 0);
//glPixelStorei(GL_UNPACK_SKIP_PIXELS, 0);
//glPixelStorei(GL_UNPACK_SKIP_ROWS, 0);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, rgbImage.cols, rgbImage.rows, 0, GL_RGBA, GL_UNSIGNED_BYTE, rgbImage.data);
GLint error = glGetError();
if(error != GL_NO_ERROR)
{
LOGE("OpenGL: Could not allocate texture (0x%x)\n", error);
textureId_ = 0;
return;
}
}
}
void CameraMobile::addEnvSensor(int type, float value)
{
lastEnvSensors_.insert(std::make_pair((EnvSensor::Type)type, EnvSensor((EnvSensor::Type)type, value)));
}
void CameraMobile::spinOnce()
{
if(!this->isRunning())
{
bool ignoreFrame = false;
//float rate = 10.0f; // maximum 10 FPS for image data
double now = UTimer::now();
/*if(rate>0.0f)
{
if((spinOncePreviousStamp_>=0.0 && now>spinOncePreviousStamp_ && now - spinOncePreviousStamp_ < 1.0f/rate) ||
((spinOncePreviousStamp_<=0.0 || now<=spinOncePreviousStamp_) && spinOnceFrameRateTimer_.getElapsedTime() < 1.0f/rate))
{
ignoreFrame = true;
}
}*/
if(!ignoreFrame)
{
spinOnceFrameRateTimer_.start();
spinOncePreviousStamp_ = now;
mainLoop();
}
else
{
// just send pose
capturePoseOnly();
}
}
}
void CameraMobile::mainLoopBegin()
{
double t = cameraStartedTime_.elapsed();
if(t < 5.0)
{
uSleep((5.0-t)*1000); // just to make sure that the camera is started
}
}
void CameraMobile::mainLoop()
{
CameraInfo info;
SensorData data = this->captureImage(&info);
if(data.isValid() && !info.odomPose.isNull())
{
if(lastKnownGPS_.stamp() > 0.0 && data.stamp()-lastKnownGPS_.stamp()<1.0)
{
data.setGPS(lastKnownGPS_);
}
else if(lastKnownGPS_.stamp()>0.0)
{
LOGD("GPS too old (current time=%f, gps time = %f)", data.stamp(), lastKnownGPS_.stamp());
}
if(lastEnvSensors_.size())
{
data.setEnvSensors(lastEnvSensors_);
lastEnvSensors_.clear();
}
if(smoothing_ && !data.depthRaw().empty())
{
//UTimer t;
data.setDepthOrRightRaw(rtabmap::util2d::fastBilateralFiltering(data.depthRaw(), bilateralFilteringSigmaS, bilateralFilteringSigmaR));
//LOGD("Bilateral filtering, time=%fs", t.ticks());
}
// Rotate image depending on the camera orientation
if(colorCameraToDisplayRotation_ == ROTATION_90)
{
UDEBUG("ROTATION_90");
cv::Mat rgb, depth;
cv::Mat rgbt(data.imageRaw().cols, data.imageRaw().rows, data.imageRaw().type());
cv::flip(data.imageRaw(),rgb,1);
cv::transpose(rgb,rgbt);
rgb = rgbt;
cv::Mat deptht(data.depthRaw().cols, data.depthRaw().rows, data.depthRaw().type());
cv::flip(data.depthRaw(),depth,1);
cv::transpose(depth,deptht);
depth = deptht;
CameraModel model = data.cameraModels()[0];
cv::Size sizet(model.imageHeight(), model.imageWidth());
model = CameraModel(
model.fy(),
model.fx(),
model.cy(),
model.cx()>0?model.imageWidth()-model.cx():0,
model.localTransform()*rtabmap::Transform(0,-1,0,0, 1,0,0,0, 0,0,1,0));
model.setImageSize(sizet);
data.setRGBDImage(rgb, depth, model);
std::vector<cv::KeyPoint> keypoints = data.keypoints();
for(size_t i=0; i<keypoints.size(); ++i)
{
keypoints[i].pt.x = data.keypoints()[i].pt.y;
keypoints[i].pt.y = rgb.rows - data.keypoints()[i].pt.x;
}
data.setFeatures(keypoints, data.keypoints3D(), cv::Mat());
}
else if(colorCameraToDisplayRotation_ == ROTATION_180)
{
UDEBUG("ROTATION_180");
cv::Mat rgb, depth;
cv::flip(data.imageRaw(),rgb,1);
cv::flip(rgb,rgb,0);
cv::flip(data.depthOrRightRaw(),depth,1);
cv::flip(depth,depth,0);
CameraModel model = data.cameraModels()[0];
cv::Size sizet(model.imageWidth(), model.imageHeight());
model = CameraModel(
model.fx(),
model.fy(),
model.cx()>0?model.imageWidth()-model.cx():0,
model.cy()>0?model.imageHeight()-model.cy():0,
model.localTransform()*rtabmap::Transform(0,0,0,0,0,1,0));
model.setImageSize(sizet);
data.setRGBDImage(rgb, depth, model);
std::vector<cv::KeyPoint> keypoints = data.keypoints();
for(size_t i=0; i<keypoints.size(); ++i)
{
keypoints[i].pt.x = rgb.cols - data.keypoints()[i].pt.x;
keypoints[i].pt.y = rgb.rows - data.keypoints()[i].pt.y;
}
data.setFeatures(keypoints, data.keypoints3D(), cv::Mat());
}
else if(colorCameraToDisplayRotation_ == ROTATION_270)
{
UDEBUG("ROTATION_270");
cv::Mat rgb(data.imageRaw().cols, data.imageRaw().rows, data.imageRaw().type());
cv::transpose(data.imageRaw(),rgb);
cv::flip(rgb,rgb,1);
cv::Mat depth(data.depthOrRightRaw().cols, data.depthOrRightRaw().rows, data.depthOrRightRaw().type());
cv::transpose(data.depthOrRightRaw(),depth);
cv::flip(depth,depth,1);
CameraModel model = data.cameraModels()[0];
cv::Size sizet(model.imageHeight(), model.imageWidth());
model = CameraModel(
model.fy(),
model.fx(),
model.cy()>0?model.imageHeight()-model.cy():0,
model.cx(),
model.localTransform()*rtabmap::Transform(0,1,0,0, -1,0,0,0, 0,0,1,0));
model.setImageSize(sizet);
data.setRGBDImage(rgb, depth, model);
std::vector<cv::KeyPoint> keypoints = data.keypoints();
for(size_t i=0; i<keypoints.size(); ++i)
{
keypoints[i].pt.x = rgb.cols - data.keypoints()[i].pt.y;
keypoints[i].pt.y = data.keypoints()[i].pt.x;
}
data.setFeatures(keypoints, data.keypoints3D(), cv::Mat());
}
rtabmap::Transform pose = info.odomPose;
data.setGroundTruth(Transform());
// convert stamp to epoch
bool firstFrame = previousPose_.isNull();
if(firstFrame)
{
stampEpochOffset_ = UTimer::now()-data.stamp();
}
data.setStamp(stampEpochOffset_ + data.stamp());
OdometryInfo info;
if(!firstFrame)
{
info.interval = data.stamp()-previousStamp_;
info.transform = previousPose_.inverse() * pose;
}
// linear cov = 0.0001
info.reg.covariance = cv::Mat::eye(6,6,CV_64FC1) * (firstFrame?9999.0:0.0001);
if(!firstFrame)
{
// angular cov = 0.000001
info.reg.covariance.at<double>(3,3) *= 0.01;
info.reg.covariance.at<double>(4,4) *= 0.01;
info.reg.covariance.at<double>(5,5) *= 0.01;
}
LOGI("Publish odometry message (variance=%f)", firstFrame?9999:0.0001);
this->post(new OdometryEvent(data, pose, info));
previousPose_ = pose;
previousStamp_ = data.stamp();
}
else if(!this->isKilled() && info.odomPose.isNull())
{
LOGW("Odometry lost");
this->post(new OdometryEvent());
}
}
SensorData CameraMobile::captureImage(CameraInfo * info)
{
if(info)
{
info->odomPose = pose_;
}
return data_;
}
LaserScan CameraMobile::scanFromPointCloudData(
const cv::Mat & pointCloudData,
int points,
const Transform & pose,
const CameraModel & model,
const cv::Mat & rgb,
std::vector<cv::KeyPoint> * kpts,
std::vector<cv::Point3f> * kpts3D,
int kptsSize)
{
if(!pointCloudData.empty())
{
cv::Mat scanData(1, pointCloudData.cols, CV_32FC4);
float * ptr = scanData.ptr<float>();
const float * inPtr = pointCloudData.ptr<float>();
int ic = pointCloudData.channels();
UASSERT(pointCloudData.depth() == CV_32F && ic >= 3);
int oi = 0;
for(unsigned int i=0;i<points; ++i)
{
cv::Point3f pt(inPtr[i*ic], inPtr[i*ic + 1], inPtr[i*ic + 2]);
pt = util3d::transformPoint(pt, pose.inverse()*rtabmap_world_T_opengl_world);
ptr[oi*4] = pt.x;
ptr[oi*4 + 1] = pt.y;
ptr[oi*4 + 2] = pt.z;
//get color from rgb image
cv::Point3f org= pt;
pt = util3d::transformPoint(pt, opticalRotationInv);
if(pt.z > 0)
{
int u,v;
model.reproject(pt.x, pt.y, pt.z, u, v);
unsigned char r=255,g=255,b=255;
if(model.inFrame(u, v))
{
b=rgb.at<cv::Vec3b>(v,u).val[0];
g=rgb.at<cv::Vec3b>(v,u).val[1];
r=rgb.at<cv::Vec3b>(v,u).val[2];
if(kpts)
kpts->push_back(cv::KeyPoint(u,v,kptsSize));
if(kpts3D)
kpts3D->push_back(org);
*(int*)&ptr[oi*4 + 3] = int(b) | (int(g) << 8) | (int(r) << 16);
++oi;
}
}
//confidence
//*(int*)&ptr[i*4 + 3] = (int(pointCloudData[i*4 + 3] * 255.0f) << 8) | (int(255) << 16);
}
return LaserScan::backwardCompatibility(scanData.colRange(0, oi), 0, 10, rtabmap::Transform::getIdentity());
}
return LaserScan();
}
} /* namespace rtabmap */
+163
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 CAMERAMOBILE_H_
#define CAMERAMOBILE_H_
#include <rtabmap/core/Camera.h>
#include <rtabmap/core/GeodeticCoords.h>
#include <rtabmap/utilite/UMutex.h>
#include <rtabmap/utilite/USemaphore.h>
#include <rtabmap/utilite/UEventsSender.h>
#include <rtabmap/utilite/UThread.h>
#include <rtabmap/utilite/UEvent.h>
#include <rtabmap/utilite/UTimer.h>
#include <boost/thread/mutex.hpp>
#include "util.h"
namespace rtabmap {
class CameraInfoEvent: public UEvent
{
public:
CameraInfoEvent(int type, const std::string & key, const std::string & value) : type_(type), key_(key), value_(value) {}
virtual std::string getClassName() const {return "CameraInfoEvent";}
int type() const {return type_;}
const std::string & key() const {return key_;}
const std::string & value() const {return value_;}
private:
int type_;
std::string key_;
std::string value_;
};
class PoseEvent: public UEvent
{
public:
PoseEvent(const Transform & pose) : pose_(pose) {}
virtual std::string getClassName() const {return "PoseEvent";}
const Transform & pose() const {return pose_;}
private:
Transform pose_;
};
class CameraMobile : public Camera, public UThread, public UEventsSender {
public:
static const float bilateralFilteringSigmaS;
static const float bilateralFilteringSigmaR;
static const rtabmap::Transform opticalRotation;
static const rtabmap::Transform opticalRotationInv;
public:
static LaserScan scanFromPointCloudData(
const cv::Mat & pointCloudData,
int points,
const Transform & pose,
const CameraModel & model,
const cv::Mat & rgb,
std::vector<cv::KeyPoint> * kpts = 0,
std::vector<cv::Point3f> * kpts3D = 0,
int kptsSize = 3);
public:
CameraMobile(bool smoothing = false);
virtual ~CameraMobile();
// abstract functions
virtual bool init(const std::string & calibrationFolder = ".", const std::string & cameraName = "");
virtual void close(); // inherited classes should call its parent in their close().
virtual std::string getSerial() const {return "CameraMobile";}
const Transform & getOriginOffset() const {return originOffset_;} // in rtabmap frame
void resetOrigin();
virtual bool isCalibrated() const;
void poseReceived(const Transform & pose); // in rtabmap frame
const CameraModel & getCameraModel() const {return model_;}
const Transform & getDeviceTColorCamera() const {return deviceTColorCamera_;}
void setSmoothing(bool enabled) {smoothing_ = enabled;}
virtual void setScreenRotationAndSize(ScreenRotation colorCameraToDisplayRotation, int width, int height) {colorCameraToDisplayRotation_ = colorCameraToDisplayRotation;}
void setGPS(const GPS & gps);
void addEnvSensor(int type, float value);
void setData(const SensorData & data, const Transform & pose, const glm::mat4 & viewMatrix, const glm::mat4 & projectionMatrix, const float * texCoord);
void spinOnce(); // Should only be called if not thread is not running, otherwise it does nothing
GLuint getTextureId() {return textureId_;}
bool uvsInitialized() const {return uvs_initialized_;}
const float* uvsTransformed() const {return transformed_uvs_;}
void getVPMatrices(glm::mat4 & view, glm::mat4 & projection) const {view=viewMatrix_; projection=projectionMatrix_;}
ScreenRotation getScreenRotation() const {return colorCameraToDisplayRotation_;}
void setOcclusionImage(const cv::Mat & image, const CameraModel & model) {occlusionModel_ = model; occlusionImage_ = image;}
const cv::Mat & getOcclusionImage(CameraModel * model=0) const {if(model)*model=occlusionModel_; return occlusionImage_; }
protected:
virtual SensorData captureImage(CameraInfo * info = 0);
virtual void capturePoseOnly() {}
virtual void mainLoopBegin();
virtual void mainLoop();
protected:
CameraModel model_; // local transform is the device to camera optical rotation in rtabmap frame
Transform deviceTColorCamera_; // device to camera optical rotation in rtabmap frame
UTimer spinOnceFrameRateTimer_;
double spinOncePreviousStamp_;
GLuint textureId_;
glm::mat4 viewMatrix_;
glm::mat4 projectionMatrix_;
float transformed_uvs_[8];
bool uvs_initialized_ = false;
private:
Transform previousPose_;
double previousStamp_;
UTimer cameraStartedTime_;
double stampEpochOffset_;
bool smoothing_;
ScreenRotation colorCameraToDisplayRotation_;
GPS lastKnownGPS_;
EnvSensors lastEnvSensors_;
Transform originOffset_;
bool originUpdate_;
SensorData data_;
Transform pose_;
cv::Mat occlusionImage_;
CameraModel occlusionModel_;
};
} /* namespace rtabmap */
#endif /* CAMERATANGO_H_ */
+360 -438
View File
@@ -33,6 +33,7 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include "rtabmap/core/util2d.h" #include "rtabmap/core/util2d.h"
#include <tango_client_api.h> #include <tango_client_api.h>
#include <tango_support_api.h> #include <tango_support_api.h>
#include "tango-gl/camera.h"
namespace rtabmap { namespace rtabmap {
@@ -42,11 +43,22 @@ const int holeSize = 5;
const float maxDepthError = 0.10; const float maxDepthError = 0.10;
const int scanDownsampling = 1; const int scanDownsampling = 1;
//android phone
//11 10 01 00 // portrait
//01 11 00 10 // left
//10 00 11 01 // right
//00 01 10 11 // down
const float kTextureCoords0[] = {1.0, 1.0, 1.0, 0.0, 0.0, 1.0, 0.0, 0.0};
const float kTextureCoords90[] = {0.0, 1.0, 1.0, 1.0, 0.0, 0.0, 1.0, 0.0};
const float kTextureCoords180[] = {0.0, 0.0, 0.0, 1.0, 1.0, 0.0, 1.0, 1.0};
const float kTextureCoords270[] = {1.0, 0.0, 0.0, 0.0, 1.0, 1.0, 0.0, 1.0};
// Callbacks // Callbacks
void onPointCloudAvailableRouter(void* context, const TangoPointCloud* point_cloud) void onPointCloudAvailableRouter(void* context, const TangoPointCloud* point_cloud)
{ {
CameraTango* app = static_cast<CameraTango*>(context); CameraTango* app = static_cast<CameraTango*>(context);
if(app->isRunning() && point_cloud->num_points>0) if(point_cloud->num_points>0)
{ {
app->cloudReceived(cv::Mat(1, point_cloud->num_points, CV_32FC4, point_cloud->points[0]), point_cloud->timestamp); app->cloudReceived(cv::Mat(1, point_cloud->num_points, CV_32FC4, point_cloud->points[0]), point_cloud->timestamp);
} }
@@ -55,34 +67,32 @@ void onPointCloudAvailableRouter(void* context, const TangoPointCloud* point_clo
void onFrameAvailableRouter(void* context, TangoCameraId id, const TangoImageBuffer* color) void onFrameAvailableRouter(void* context, TangoCameraId id, const TangoImageBuffer* color)
{ {
CameraTango* app = static_cast<CameraTango*>(context); CameraTango* app = static_cast<CameraTango*>(context);
if(app->isRunning())
{
cv::Mat tangoImage;
if(color->format == TANGO_HAL_PIXEL_FORMAT_RGBA_8888)
{
tangoImage = cv::Mat(color->height, color->width, CV_8UC4, color->data);
}
else if(color->format == TANGO_HAL_PIXEL_FORMAT_YV12)
{
tangoImage = cv::Mat(color->height+color->height/2, color->width, CV_8UC1, color->data);
}
else if(color->format == TANGO_HAL_PIXEL_FORMAT_YCrCb_420_SP)
{
tangoImage = cv::Mat(color->height+color->height/2, color->width, CV_8UC1, color->data);
}
else if(color->format == 35)
{
tangoImage = cv::Mat(color->height+color->height/2, color->width, CV_8UC1, color->data);
}
else
{
LOGE("Not supported color format : %d.", color->format);
}
if(!tangoImage.empty()) cv::Mat tangoImage;
{ if(color->format == TANGO_HAL_PIXEL_FORMAT_RGBA_8888)
app->rgbReceived(tangoImage, (unsigned int)color->format, color->timestamp); {
} tangoImage = cv::Mat(color->height, color->width, CV_8UC4, color->data);
}
else if(color->format == TANGO_HAL_PIXEL_FORMAT_YV12)
{
tangoImage = cv::Mat(color->height+color->height/2, color->width, CV_8UC1, color->data);
}
else if(color->format == TANGO_HAL_PIXEL_FORMAT_YCrCb_420_SP)
{
tangoImage = cv::Mat(color->height+color->height/2, color->width, CV_8UC1, color->data);
}
else if(color->format == 35)
{
tangoImage = cv::Mat(color->height+color->height/2, color->width, CV_8UC1, color->data);
}
else
{
LOGE("Not supported color format : %d.", color->format);
}
if(!tangoImage.empty())
{
app->rgbReceived(tangoImage, (unsigned int)color->format, color->timestamp);
} }
} }
@@ -91,7 +101,7 @@ void onPoseAvailableRouter(void* context, const TangoPoseData* pose)
if(pose->status_code == TANGO_POSE_VALID) if(pose->status_code == TANGO_POSE_VALID)
{ {
CameraTango* app = static_cast<CameraTango*>(context); CameraTango* app = static_cast<CameraTango*>(context);
app->poseReceived(app->tangoPoseToTransform(pose)); app->poseReceived(rtabmap_world_T_tango_world * app->tangoPoseToTransform(pose) * tango_device_T_rtabmap_world);
} }
} }
@@ -104,23 +114,14 @@ void onTangoEventAvailableRouter(void* context, const TangoEvent* event)
////////////////////////////// //////////////////////////////
// CameraTango // CameraTango
////////////////////////////// //////////////////////////////
const float CameraTango::bilateralFilteringSigmaS = 2.0f;
const float CameraTango::bilateralFilteringSigmaR = 0.075f;
CameraTango::CameraTango(bool colorCamera, int decimation, bool publishRawScan, bool smoothing) : CameraTango::CameraTango(bool colorCamera, int decimation, bool publishRawScan, bool smoothing) :
Camera(0), CameraMobile(smoothing),
tango_config_(0), tango_config_(0),
previousStamp_(0.0),
stampEpochOffset_(0.0),
colorCamera_(colorCamera), colorCamera_(colorCamera),
decimation_(decimation), decimation_(decimation),
rawScanPublished_(publishRawScan), rawScanPublished_(publishRawScan),
smoothing_(smoothing),
cloudStamp_(0),
tangoColorType_(0), tangoColorType_(0),
tangoColorStamp_(0), tangoColorStamp_(0)
colorCameraToDisplayRotation_(ROTATION_0),
originUpdate_(false)
{ {
UASSERT(decimation >= 1); UASSERT(decimation >= 1);
} }
@@ -350,6 +351,7 @@ bool CameraTango::init(const std::string & calibrationFolder, const std::string
pose_data.orientation[1], pose_data.orientation[1],
pose_data.orientation[2], pose_data.orientation[2],
pose_data.orientation[3]); pose_data.orientation[3]);
deviceTColorCamera_ = rtabmap_world_T_opengl_world * deviceTColorCamera_;
// camera intrinsic // camera intrinsic
TangoCameraIntrinsics color_camera_intrinsics; TangoCameraIntrinsics color_camera_intrinsics;
@@ -408,18 +410,14 @@ bool CameraTango::init(const std::string & calibrationFolder, const std::string
model_ = CameraModel(colorCamera_?"color":"fisheye", model_ = CameraModel(colorCamera_?"color":"fisheye",
cv::Size(color_camera_intrinsics.width, color_camera_intrinsics.height), cv::Size(color_camera_intrinsics.width, color_camera_intrinsics.height),
K, D, R, P, K, D, R, P,
tango_device_T_rtabmap_device.inverse()*deviceTColorCamera_); // device to camera optical rotation in rtabmap frame deviceTColorCamera_);
if(!colorCamera_) if(!colorCamera_)
{ {
initFisheyeRectificationMap(model_, fisheyeRectifyMapX_, fisheyeRectifyMapY_); initFisheyeRectificationMap(model_, fisheyeRectifyMapX_, fisheyeRectifyMapY_);
} }
LOGI("deviceTColorCameraTango =%s", deviceTColorCamera_.prettyPrint().c_str()); LOGI("deviceTColorCameraRtabmap =%s", deviceTColorCamera_.prettyPrint().c_str());
LOGI("deviceTColorCameraRtabmap=%s", (tango_device_T_rtabmap_device.inverse()*deviceTColorCamera_).prettyPrint().c_str());
cameraStartedTime_.restart();
return true; return true;
} }
@@ -433,23 +431,15 @@ void CameraTango::close()
TangoService_disconnect(); TangoService_disconnect();
LOGI("TangoService_disconnect() done."); LOGI("TangoService_disconnect() done.");
} }
previousPose_.setNull();
previousStamp_ = 0.0;
fisheyeRectifyMapX_ = cv::Mat(); fisheyeRectifyMapX_ = cv::Mat();
fisheyeRectifyMapY_ = cv::Mat(); fisheyeRectifyMapY_ = cv::Mat();
lastKnownGPS_ = GPS();
originOffset_ = Transform();
originUpdate_ = false;
}
void CameraTango::resetOrigin() CameraMobile::close();
{
originUpdate_ = true;
} }
void CameraTango::cloudReceived(const cv::Mat & cloud, double timestamp) void CameraTango::cloudReceived(const cv::Mat & cloud, double timestamp)
{ {
if(this->isRunning() && !cloud.empty()) if(!cloud.empty())
{ {
//LOGD("Depth received! %fs (%d points)", timestamp, cloud.cols); //LOGD("Depth received! %fs (%d points)", timestamp, cloud.cols);
@@ -466,20 +456,248 @@ void CameraTango::cloudReceived(const cv::Mat & cloud, double timestamp)
// So, synchronize with the last RGB frame before the Depth is acquired // So, synchronize with the last RGB frame before the Depth is acquired
if(!tangoColor_.empty()) if(!tangoColor_.empty())
{ {
UTimer timer;
double dt = fabs(timestamp - tangoColorStamp_); double dt = fabs(timestamp - tangoColorStamp_);
//LOGD("Depth: %f vs %f = %f", tangoColorStamp_, timestamp, dt); //LOGD("Depth: %f vs %f = %f", tangoColorStamp_, timestamp, dt);
if(dt >= 0.0 && dt < 0.5) if(dt >= 0.0 && dt < 0.5)
{ {
bool notify = cloud_.empty(); bool notify = !data_.isValid();
cloud_ = cloud.clone();
cloudStamp_ = timestamp; cv::Mat tangoImage = tangoColor_;
cv::Mat rgb;
double cloudStamp = timestamp;
double rgbStamp = tangoColorStamp_;
int tangoColorType = tangoColorType_;
tangoColor_ = cv::Mat();
tangoColorStamp_ = 0.0;
tangoColorType_ = 0;
LOGD("tangoColorType=%d", tangoColorType);
if(tangoColorType == TANGO_HAL_PIXEL_FORMAT_RGBA_8888)
{
cv::cvtColor(tangoImage, rgb, cv::COLOR_RGBA2BGR);
}
else if(tangoColorType == TANGO_HAL_PIXEL_FORMAT_YV12)
{
cv::cvtColor(tangoImage, rgb, cv::COLOR_YUV2BGR_YV12);
}
else if(tangoColorType == TANGO_HAL_PIXEL_FORMAT_YCrCb_420_SP)
{
cv::cvtColor(tangoImage, rgb, cv::COLOR_YUV2BGR_NV21);
}
else if(tangoColorType == 35)
{
cv::cvtColor(tangoImage, rgb, cv::COLOR_YUV420sp2GRAY);
}
else
{
LOGE("Not supported color format : %d.", tangoColorType);
data_ = SensorData();
return;
}
//for(int i=0; i<rgb.cols; ++i)
//{
// UERROR("%d,%d,%d", (int)rgb.at<cv::Vec3b>(i)[0], (int)rgb.at<cv::Vec3b>(i)[1], (int)rgb.at<cv::Vec3b>(i)[2]);
//}
CameraModel model = model_;
if(colorCamera_)
{
if(decimation_ > 1)
{
rgb = util2d::decimate(rgb, decimation_);
model = model.scaled(1.0/double(decimation_));
}
}
else
{
//UTimer t;
cv::Mat rgbRect;
cv::remap(rgb, rgbRect, fisheyeRectifyMapX_, fisheyeRectifyMapY_, cv::INTER_LINEAR, cv::BORDER_CONSTANT, 0);
rgb = rgbRect;
//LOGD("Rectification time=%fs", t.ticks());
}
// Querying the depth image's frame transformation based on the depth image's
// timestamp.
cv::Mat depth;
// 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, colorCamera_?TANGO_COORDINATE_FRAME_CAMERA_COLOR:TANGO_COORDINATE_FRAME_CAMERA_FISHEYE, cloudStamp,
TANGO_COORDINATE_FRAME_CAMERA_DEPTH,
&pose_color_image_t1_T_depth_image_t0) == TANGO_SUCCESS)
{
colorToDepth = tangoPoseToTransform(&pose_color_image_t1_T_depth_image_t0);
}
else
{
LOGE(
"SynchronizationApplication: Could not find a valid relative pose at "
"time for color and "
" depth cameras.");
}
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
// Camera frame at timestamp t1.
//LOGD("colorToDepth=%s", colorToDepth.prettyPrint().c_str());
LOGD("rgb=%dx%d cloud size=%d", rgb.cols, rgb.rows, (int)cloud.total());
int pixelsSet = 0;
int depthSizeDec = colorCamera_?8:1;
depth = cv::Mat::zeros(model_.imageHeight()/depthSizeDec, model_.imageWidth()/depthSizeDec, CV_16UC1); // mm
CameraModel depthModel = model_.scaled(1.0f/float(depthSizeDec));
std::vector<cv::Point3f> scanData(rawScanPublished_?cloud.total():0);
int oi=0;
int closePoints = 0;
float closeROI[4];
closeROI[0] = depth.cols/4;
closeROI[1] = 3*(depth.cols/4);
closeROI[2] = depth.rows/4;
closeROI[3] = 3*(depth.rows/4);
unsigned short minDepthValue=10000;
for(unsigned int i=0; i<cloud.total(); ++i)
{
const float * p = cloud.ptr<float>(0,i);
cv::Point3f pt = util3d::transformPoint(cv::Point3f(p[0], p[1], p[2]), colorToDepth);
if(pt.z > 0.0f && i%scanDownsampling == 0 && rawScanPublished_)
{
scanData.at(oi++) = pt;
}
int pixel_x_l, pixel_y_l, pixel_x_h, pixel_y_h;
// get the coordinate on image plane.
pixel_x_l = static_cast<int>((depthModel.fx()) * (pt.x / pt.z) + depthModel.cx());
pixel_y_l = static_cast<int>((depthModel.fy()) * (pt.y / pt.z) + depthModel.cy());
pixel_x_h = static_cast<int>((depthModel.fx()) * (pt.x / pt.z) + depthModel.cx() + 0.5f);
pixel_y_h = static_cast<int>((depthModel.fy()) * (pt.y / pt.z) + depthModel.cy() + 0.5f);
unsigned short depth_value(pt.z * 1000.0f);
if(pixel_x_l>=closeROI[0] && pixel_x_l<closeROI[1] &&
pixel_y_l>closeROI[2] && pixel_y_l<closeROI[3] &&
depth_value < 600)
{
++closePoints;
if(depth_value < minDepthValue)
{
minDepthValue = depth_value;
}
}
bool pixelSet = false;
if(pixel_x_l>=0 && pixel_x_l<depth.cols &&
pixel_y_l>0 && pixel_y_l<depth.rows && // ignore first line
depth_value)
{
unsigned short & depthPixel = depth.at<unsigned short>(pixel_y_l, pixel_x_l);
if(depthPixel == 0 || depthPixel > depth_value)
{
depthPixel = depth_value;
pixelSet = true;
}
}
if(pixel_x_h>=0 && pixel_x_h<depth.cols &&
pixel_y_h>0 && pixel_y_h<depth.rows && // ignore first line
depth_value)
{
unsigned short & depthPixel = depth.at<unsigned short>(pixel_y_h, pixel_x_h);
if(depthPixel == 0 || depthPixel > depth_value)
{
depthPixel = depth_value;
pixelSet = true;
}
}
if(pixelSet)
{
pixelsSet += 1;
}
}
if(closePoints > 100)
{
this->post(new CameraInfoEvent(0, "TooClose", ""));
}
if(oi)
{
scan = cv::Mat(1, oi, CV_32FC3, scanData.data()).clone();
}
//LOGD("pixels depth set= %d", pixelsSet);
}
else
{
LOGE("color to depth pose is null?!? (rgb stamp=%f) (depth stamp=%f)", rgbStamp, cloudStamp);
}
if(!rgb.empty() && !depth.empty())
{
depth = rtabmap::util2d::fillDepthHoles(depth, holeSize, maxDepthError);
Transform odom = 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());
// adjust origin
if(!getOriginOffset().isNull())
{
odom = getOriginOffset() * odom;
}
// occlusion depth
if(!depth.empty())
{
rtabmap::CameraModel depthModel = model.scaled(float(depth.cols) / float(model.imageWidth()));
depthModel.setLocalTransform(odom*model.localTransform());
this->setOcclusionImage(depth, depthModel);
}
//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());
Transform scanLocalTransform = model.localTransform();
if(rawScanPublished_)
{
data_ = SensorData(LaserScan::backwardCompatibility(scan, cloud.total()/scanDownsampling, 0, scanLocalTransform), rgb, depth, model, this->getNextSeqID(), rgbStamp);
}
else
{
data_ = SensorData(rgb, depth, model, this->getNextSeqID(), rgbStamp);
}
data_.setGroundTruth(odom);
}
else
{
LOGE("Could not get depth and rgb images!?!");
data_ = SensorData();
return;
}
if(notify) if(notify)
{ {
//LOGD("Cloud: Release semaphore");
dataReady_.release(); dataReady_.release();
} }
LOGD("process cloud received %fs", timer.ticks());
} }
} }
} }
@@ -487,7 +705,7 @@ void CameraTango::cloudReceived(const cv::Mat & cloud, double timestamp)
void CameraTango::rgbReceived(const cv::Mat & tangoImage, int type, double timestamp) void CameraTango::rgbReceived(const cv::Mat & tangoImage, int type, double timestamp)
{ {
if(this->isRunning() && !tangoImage.empty()) if(!tangoImage.empty())
{ {
//LOGD("RGB received! %fs", timestamp); //LOGD("RGB received! %fs", timestamp);
@@ -499,40 +717,9 @@ void CameraTango::rgbReceived(const cv::Mat & tangoImage, int type, double times
} }
} }
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);
void CameraTango::poseReceived(const Transform & pose)
{
if(!pose.isNull())
{
// send pose of the camera (without optical rotation), not the device
Transform p = pose*deviceTColorCamera_*opticalRotation;
if(originUpdate_)
{
originOffset_ = p.translation().inverse();
originUpdate_ = false;
}
if(!originOffset_.isNull())
{
this->post(new PoseEvent(originOffset_*p));
}
else
{
this->post(new PoseEvent(p));
}
}
}
void CameraTango::tangoEventReceived(int type, const char * key, const char * value) void CameraTango::tangoEventReceived(int type, const char * key, const char * value)
{ {
this->post(new CameraTangoEvent(type, key, value)); this->post(new CameraInfoEvent(type, key, value));
}
bool CameraTango::isCalibrated() const
{
return model_.isValidForProjection();
} }
std::string CameraTango::getSerial() const std::string CameraTango::getSerial() const
@@ -540,11 +727,6 @@ std::string CameraTango::getSerial() const
return "Tango"; return "Tango";
} }
void CameraTango::setGPS(const GPS & gps)
{
lastKnownGPS_ = gps;
}
rtabmap::Transform CameraTango::tangoPoseToTransform(const TangoPoseData * tangoPose) const rtabmap::Transform CameraTango::tangoPoseToTransform(const TangoPoseData * tangoPose) const
{ {
UASSERT(tangoPose); UASSERT(tangoPose);
@@ -587,8 +769,7 @@ rtabmap::Transform CameraTango::getPoseAtTimestamp(double timestamp)
} }
else else
{ {
pose = rtabmap_world_T_tango_world * tangoPoseToTransform(&pose_start_service_T_device) * tango_device_T_rtabmap_world;
pose = tangoPoseToTransform(&pose_start_service_T_device);
} }
return pose; return pose;
@@ -598,375 +779,116 @@ SensorData CameraTango::captureImage(CameraInfo * info)
{ {
//LOGI("Capturing image..."); //LOGI("Capturing image...");
SensorData data; if(textureId_ == 0)
if(!dataReady_.acquire(1, 2000))
{ {
if(this->isRunning()) glGenTextures(1, &textureId_);
{ glBindTexture(GL_TEXTURE_EXTERNAL_OES, textureId_);
LOGE("Not received any frames since 2 seconds, try to restart the camera again."); glTexParameteri(GL_TEXTURE_EXTERNAL_OES, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
this->post(new CameraTangoEvent(0, "CameraTango", "No frames received since 2 seconds.")); glTexParameteri(GL_TEXTURE_EXTERNAL_OES, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_EXTERNAL_OES, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
boost::mutex::scoped_lock lock(dataMutex_); glTexParameteri(GL_TEXTURE_EXTERNAL_OES, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
if(!cloud_.empty() && !tangoColor_.empty())
{
UERROR("cloud and image were set!?");
}
}
cloud_ = cv::Mat();
cloudStamp_ = 0.0;
tangoColor_ = cv::Mat();
tangoColorStamp_ = 0.0;
tangoColorType_ = 0;
} }
else
// Update Texture (optional, just for first-view rendering)
if(colorCamera_ && textureId_)
{ {
cv::Mat cloud; double video_overlay_timestamp;
cv::Mat tangoImage; TangoErrorType status = TangoService_updateTextureExternalOes(TANGO_CAMERA_COLOR, textureId_, &video_overlay_timestamp);
cv::Mat rgb;
double cloudStamp = 0.0;
double rgbStamp = 0.0;
int tangoColorType = 0;
if (status == TANGO_SUCCESS)
{ {
boost::mutex::scoped_lock lock(dataMutex_); if(info)
cloud = cloud_;
cloudStamp = cloudStamp_;
cloud_ = cv::Mat();
cloudStamp_ = 0.0;
tangoImage = tangoColor_;
rgbStamp = tangoColorStamp_;
tangoColorType = tangoColorType_;
tangoColor_ = cv::Mat();
tangoColorStamp_ = 0.0;
tangoColorType_ = 0;
}
LOGD("tangoColorType=%d", tangoColorType);
if(tangoColorType == TANGO_HAL_PIXEL_FORMAT_RGBA_8888)
{
cv::cvtColor(tangoImage, rgb, CV_RGBA2BGR);
}
else if(tangoColorType == TANGO_HAL_PIXEL_FORMAT_YV12)
{
cv::cvtColor(tangoImage, rgb, CV_YUV2BGR_YV12);
}
else if(tangoColorType == TANGO_HAL_PIXEL_FORMAT_YCrCb_420_SP)
{
cv::cvtColor(tangoImage, rgb, CV_YUV2BGR_NV21);
}
else if(tangoColorType == 35)
{
cv::cvtColor(tangoImage, rgb, cv::COLOR_YUV420sp2GRAY);
}
else
{
LOGE("Not supported color format : %d.", tangoColorType);
return data;
}
//for(int i=0; i<rgb.cols; ++i)
//{
// UERROR("%d,%d,%d", (int)rgb.at<cv::Vec3b>(i)[0], (int)rgb.at<cv::Vec3b>(i)[1], (int)rgb.at<cv::Vec3b>(i)[2]);
//}
CameraModel model = model_;
if(colorCamera_)
{
if(decimation_ > 1)
{ {
rgb = util2d::decimate(rgb, decimation_); info->odomPose = getPoseAtTimestamp(video_overlay_timestamp);
model = model.scaled(1.0/double(decimation_));
} }
}
else
{
//UTimer t;
cv::Mat rgbRect;
cv::remap(rgb, rgbRect, fisheyeRectifyMapX_, fisheyeRectifyMapY_, cv::INTER_LINEAR, cv::BORDER_CONSTANT, 0);
rgb = rgbRect;
//LOGD("Rectification time=%fs", t.ticks());
}
// Querying the depth image's frame transformation based on the depth image's int rotation = static_cast<int>(getScreenRotation()) + 1; // remove 90deg camera rotation
// timestamp. if (rotation > 3) {
cv::Mat depth; rotation -= 4;
}
// Calculate the relative pose from color camera frame at timestamp TangoDoubleMatrixTransformData matrix_transform;
// color_timestamp t1 and depth status = TangoSupport_getDoubleMatrixTransformAtTime(
// camera frame at depth_timestamp t0. video_overlay_timestamp,
Transform colorToDepth; TANGO_COORDINATE_FRAME_CAMERA_COLOR,
TangoPoseData pose_color_image_t1_T_depth_image_t0; TANGO_COORDINATE_FRAME_START_OF_SERVICE,
if (TangoSupport_calculateRelativePose( TANGO_SUPPORT_ENGINE_OPENGL,
rgbStamp, colorCamera_?TANGO_COORDINATE_FRAME_CAMERA_COLOR:TANGO_COORDINATE_FRAME_CAMERA_FISHEYE, cloudStamp, TANGO_SUPPORT_ENGINE_OPENGL,
TANGO_COORDINATE_FRAME_CAMERA_DEPTH, static_cast<TangoSupportRotation>(rotation),
&pose_color_image_t1_T_depth_image_t0) == TANGO_SUCCESS) &matrix_transform);
{ if (matrix_transform.status_code == TANGO_POSE_VALID)
colorToDepth = tangoPoseToTransform(&pose_color_image_t1_T_depth_image_t0);
}
else
{
LOGE(
"SynchronizationApplication: Could not find a valid relative pose at "
"time for color and "
" depth cameras.");
}
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
// Camera frame at timestamp t1.
//LOGD("colorToDepth=%s", colorToDepth.prettyPrint().c_str());
LOGD("rgb=%dx%d cloud size=%d", rgb.cols, rgb.rows, (int)cloud.total());
int pixelsSet = 0;
int depthSizeDec = colorCamera_?8:1;
depth = cv::Mat::zeros(model_.imageHeight()/depthSizeDec, model_.imageWidth()/depthSizeDec, CV_16UC1); // mm
CameraModel depthModel = model_.scaled(1.0f/float(depthSizeDec));
std::vector<cv::Point3f> scanData(rawScanPublished_?cloud.total():0);
int oi=0;
int closePoints = 0;
float closeROI[4];
closeROI[0] = depth.cols/4;
closeROI[1] = 3*(depth.cols/4);
closeROI[2] = depth.rows/4;
closeROI[3] = 3*(depth.rows/4);
unsigned short minDepthValue=10000;
for(unsigned int i=0; i<cloud.total(); ++i)
{ {
float * p = cloud.ptr<float>(0,i); // Get projection matrix
cv::Point3f pt = util3d::transformPoint(cv::Point3f(p[0], p[1], p[2]), colorToDepth); TangoCameraIntrinsics color_camera_intrinsics;
int ret = TangoSupport_getCameraIntrinsicsBasedOnDisplayRotation(
TANGO_CAMERA_COLOR,
static_cast<TangoSupportRotation>(rotation),
&color_camera_intrinsics);
if(pt.z > 0.0f && i%scanDownsampling == 0 && rawScanPublished_) if (ret == TANGO_SUCCESS) {
{ float image_width = static_cast<float>(color_camera_intrinsics.width);
scanData.at(oi++) = pt; float image_height = static_cast<float>(color_camera_intrinsics.height);
} float fx = static_cast<float>(color_camera_intrinsics.fx);
float fy = static_cast<float>(color_camera_intrinsics.fy);
float cx = static_cast<float>(color_camera_intrinsics.cx);
float cy = static_cast<float>(color_camera_intrinsics.cy);
int pixel_x_l, pixel_y_l, pixel_x_h, pixel_y_h; viewMatrix_ = glm::make_mat4(matrix_transform.matrix);
// get the coordinate on image plane. if(!getOriginOffset().isNull())
pixel_x_l = static_cast<int>((depthModel.fx()) * (pt.x / pt.z) + depthModel.cx());
pixel_y_l = static_cast<int>((depthModel.fy()) * (pt.y / pt.z) + depthModel.cy());
pixel_x_h = static_cast<int>((depthModel.fx()) * (pt.x / pt.z) + depthModel.cx() + 0.5f);
pixel_y_h = static_cast<int>((depthModel.fy()) * (pt.y / pt.z) + depthModel.cy() + 0.5f);
unsigned short depth_value(pt.z * 1000.0f);
if(pixel_x_l>=closeROI[0] && pixel_x_l<closeROI[1] &&
pixel_y_l>closeROI[2] && pixel_y_l<closeROI[3] &&
depth_value < 600)
{
++closePoints;
if(depth_value < minDepthValue)
{ {
minDepthValue = depth_value; viewMatrix_ = glm::inverse(rtabmap::glmFromTransform(rtabmap::opengl_world_T_rtabmap_world * getOriginOffset() *rtabmap::rtabmap_world_T_opengl_world)*glm::inverse(viewMatrix_));
} }
}
bool pixelSet = false; projectionMatrix_ = tango_gl::Camera::ProjectionMatrixForCameraIntrinsics(
if(pixel_x_l>=0 && pixel_x_l<depth.cols && image_width, image_height, fx, fy, cx, cy, 0.3, 50);
pixel_y_l>0 && pixel_y_l<depth.rows && // ignore first line
depth_value) switch(rotation)
{
unsigned short & depthPixel = depth.at<unsigned short>(pixel_y_l, pixel_x_l);
if(depthPixel == 0 || depthPixel > depth_value)
{ {
depthPixel = depth_value; case ROTATION_90:
pixelSet = true; memcpy(transformed_uvs_, kTextureCoords90, 8*sizeof(float));
break;
case ROTATION_180:
memcpy(transformed_uvs_, kTextureCoords180, 8*sizeof(float));
break;
case ROTATION_270:
memcpy(transformed_uvs_, kTextureCoords270, 8*sizeof(float));
break;
case ROTATION_0:
default:
memcpy(transformed_uvs_, kTextureCoords0, 8*sizeof(float));
} }
uvs_initialized_ = true;
} }
if(pixel_x_h>=0 && pixel_x_h<depth.cols && else
pixel_y_h>0 && pixel_y_h<depth.rows && // ignore first line
depth_value)
{ {
unsigned short & depthPixel = depth.at<unsigned short>(pixel_y_h, pixel_x_h); UERROR("TangoSupport_getCameraIntrinsicsBasedOnDisplayRotation failed!");
if(depthPixel == 0 || depthPixel > depth_value)
{
depthPixel = depth_value;
pixelSet = true;
}
} }
if(pixelSet)
{
pixelsSet += 1;
}
}
if(closePoints > 100)
{
this->post(new CameraTangoEvent(0, "TooClose", ""));
}
if(oi)
{
scan = cv::Mat(1, oi, CV_32FC3, scanData.data()).clone();
}
//LOGD("pixels depth set= %d", pixelsSet);
}
else
{
LOGE("color to depth pose is null?!? (rgb stamp=%f) (depth stamp=%f)", rgbStamp, cloudStamp);
}
if(!rgb.empty() && !depth.empty())
{
depth = rtabmap::util2d::fillDepthHoles(depth, holeSize, maxDepthError);
Transform poseDevice = getPoseAtTimestamp(rgbStamp);
// adjust origin
if(!originOffset_.isNull())
{
poseDevice = originOffset_ * poseDevice;
}
//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
Transform odom = rtabmap_world_T_tango_world * poseDevice * tango_device_T_rtabmap_device;
//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());
Transform scanLocalTransform = model.localTransform();
// Rotate image depending on the camera orientation
if(colorCameraToDisplayRotation_ == ROTATION_90)
{
cv::Mat rgbt(rgb.cols, rgb.rows, rgb.type());
cv::flip(rgb,rgb,1);
cv::transpose(rgb,rgbt);
rgb = rgbt;
cv::Mat deptht(depth.cols, depth.rows, depth.type());
cv::flip(depth,depth,1);
cv::transpose(depth,deptht);
depth = deptht;
cv::Size sizet(model.imageHeight(), model.imageWidth());
model = CameraModel(model.fy(), model.fx(), model.cy(), model.cx()>0?model.imageWidth()-model.cx():0, model.localTransform()*rtabmap::Transform(0,0,0,0,0,1.57079632679489661923132169163975144));
model.setImageSize(sizet);
}
else if(colorCameraToDisplayRotation_ == ROTATION_180)
{
cv::flip(rgb,rgb,1);
cv::flip(rgb,rgb,0);
cv::flip(depth,depth,1);
cv::flip(depth,depth,0);
cv::Size sizet(model.imageWidth(), model.imageHeight());
model = CameraModel(
model.fx(),
model.fy(),
model.cx()>0?model.imageWidth()-model.cx():0,
model.cy()>0?model.imageHeight()-model.cy():0,
model.localTransform()*rtabmap::Transform(0,0,0,0,0,1.57079632679489661923132169163975144*2.0));
model.setImageSize(sizet);
}
else if(colorCameraToDisplayRotation_ == ROTATION_270)
{
cv::Mat rgbt(rgb.cols, rgb.rows, rgb.type());
cv::transpose(rgb,rgbt);
cv::flip(rgbt,rgbt,1);
rgb = rgbt;
cv::Mat deptht(depth.cols, depth.rows, depth.type());
cv::transpose(depth,deptht);
cv::flip(deptht,deptht,1);
depth = deptht;
cv::Size sizet(model.imageHeight(), model.imageWidth());
model = CameraModel(model.fy(), model.fx(), model.cy()>0?model.imageHeight()-model.cy():0, model.cx(), model.localTransform()*rtabmap::Transform(0,0,0,0,0,-1.57079632679489661923132169163975144));
model.setImageSize(sizet);
}
if(smoothing_)
{
//UTimer t;
depth = rtabmap::util2d::fastBilateralFiltering(depth, bilateralFilteringSigmaS, bilateralFilteringSigmaR);
data.setDepthOrRightRaw(depth);
//LOGD("Bilateral filtering, time=%fs", t.ticks());
}
if(rawScanPublished_)
{
data = SensorData(LaserScan::backwardCompatibility(scan, cloud.total()/scanDownsampling, 0, scanLocalTransform), rgb, depth, model, this->getNextSeqID(), rgbStamp);
} }
else else
{ {
data = SensorData(rgb, depth, model, this->getNextSeqID(), rgbStamp); UERROR("TangoSupport_getDoubleMatrixTransformAtTime failed!");
}
data.setGroundTruth(odom);
if(lastKnownGPS_.stamp() > 0.0 && rgbStamp-lastKnownGPS_.stamp()<1.0)
{
data.setGPS(lastKnownGPS_);
}
else if(lastKnownGPS_.stamp()>0.0)
{
LOGD("GPS too old (current time=%f, gps time = %f)", rgbStamp, lastKnownGPS_.stamp());
} }
} }
else else
{ {
LOGE("Could not get depth and rgb images!?!"); UERROR("TangoService_updateTextureExternalOes failed!");
}
}
SensorData data;
if(dataReady_.acquireTry(1))
{
boost::mutex::scoped_lock lock(dataMutex_);
data = data_;
data_ = SensorData();
if(info)
{
info->odomPose = data.groundTruth();
data.setGroundTruth(Transform());
} }
} }
return data; return data;
} }
void CameraTango::mainLoopBegin()
{
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()
{
if(tango_config_)
{
SensorData data = this->captureImage();
if(!data.groundTruth().isNull())
{
rtabmap::Transform pose = data.groundTruth();
data.setGroundTruth(Transform());
// convert stamp to epoch
bool firstFrame = previousPose_.isNull();
if(firstFrame)
{
stampEpochOffset_ = UTimer::now()-data.stamp();
}
data.setStamp(stampEpochOffset_ + data.stamp());
OdometryInfo info;
if(!firstFrame)
{
info.interval = data.stamp()-previousStamp_;
info.transform = previousPose_.inverse() * pose;
}
info.reg.covariance = cv::Mat::eye(6,6,CV_64FC1) * (firstFrame?9999.0:0.0001);
LOGI("Publish odometry message (variance=%f)", firstFrame?9999:0.0001);
this->post(new OdometryEvent(data, pose, info));
previousPose_ = pose;
previousStamp_ = data.stamp();
}
else if(!this->isKilled())
{
LOGW("Odometry lost");
this->post(new OdometryEvent());
}
}
else
{
UERROR("Camera not initialized, cannot start thread.");
this->kill();
}
}
} /* namespace rtabmap */ } /* namespace rtabmap */
+5 -58
View File
@@ -28,6 +28,7 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#ifndef CAMERATANGO_H_ #ifndef CAMERATANGO_H_
#define CAMERATANGO_H_ #define CAMERATANGO_H_
#include "CameraMobile.h"
#include <rtabmap/core/Camera.h> #include <rtabmap/core/Camera.h>
#include <rtabmap/core/GeodeticCoords.h> #include <rtabmap/core/GeodeticCoords.h>
#include <rtabmap/utilite/UMutex.h> #include <rtabmap/utilite/UMutex.h>
@@ -37,65 +38,26 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include <rtabmap/utilite/UEvent.h> #include <rtabmap/utilite/UEvent.h>
#include <rtabmap/utilite/UTimer.h> #include <rtabmap/utilite/UTimer.h>
#include <boost/thread/mutex.hpp> #include <boost/thread/mutex.hpp>
#include <tango_client_api.h>
#include <tango_support_api.h> #include <tango_support_api.h>
class TangoPoseData;
namespace rtabmap { namespace rtabmap {
class PoseEvent: public UEvent class CameraTango : public CameraMobile {
{
public:
PoseEvent(const Transform & pose) : pose_(pose) {}
virtual std::string getClassName() const {return "PoseEvent";}
const Transform & pose() const {return pose_;}
private:
Transform pose_;
};
class CameraTangoEvent: public UEvent
{
public:
CameraTangoEvent(int type, const std::string & key, const std::string & value) : type_(type), key_(key), value_(value) {}
virtual std::string getClassName() const {return "CameraTangoEvent";}
int type() const {return type_;}
const std::string & key() const {return key_;}
const std::string & value() const {return value_;}
private:
int type_;
std::string key_;
std::string value_;
};
class CameraTango : public Camera, public UThread, public UEventsSender {
public:
static const float bilateralFilteringSigmaS;
static const float bilateralFilteringSigmaR;
public: public:
CameraTango(bool colorCamera, int decimation, bool publishRawScan, bool smoothing); CameraTango(bool colorCamera, int decimation, bool publishRawScan, bool smoothing);
virtual ~CameraTango(); virtual ~CameraTango();
virtual bool init(const std::string & calibrationFolder = ".", const std::string & cameraName = ""); virtual bool init(const std::string & calibrationFolder = ".", const std::string & cameraName = "");
void close(); // close Tango connection virtual void close(); // close Tango connection
void resetOrigin();
virtual bool isCalibrated() const;
virtual std::string getSerial() const; virtual std::string getSerial() const;
const CameraModel & getCameraModel() const {return model_;}
rtabmap::Transform tangoPoseToTransform(const TangoPoseData * tangoPose) const; rtabmap::Transform tangoPoseToTransform(const TangoPoseData * tangoPose) const;
void setColorCamera(bool enabled) {if(!this->isRunning()) colorCamera_ = enabled;} void setColorCamera(bool enabled) {if(!this->isRunning()) colorCamera_ = enabled;}
void setDecimation(int value) {decimation_ = value;} void setDecimation(int value) {decimation_ = value;}
void setSmoothing(bool enabled) {smoothing_ = enabled;}
void setRawScanPublished(bool enabled) {rawScanPublished_ = enabled;} void setRawScanPublished(bool enabled) {rawScanPublished_ = enabled;}
void setScreenRotation(TangoSupportRotation colorCameraToDisplayRotation) {colorCameraToDisplayRotation_ = colorCameraToDisplayRotation;}
void setGPS(const GPS & gps);
void cloudReceived(const cv::Mat & cloud, double timestamp); void cloudReceived(const cv::Mat & cloud, double timestamp);
void rgbReceived(const cv::Mat & tangoImage, int type, double timestamp); void rgbReceived(const cv::Mat & tangoImage, int type, double timestamp);
void poseReceived(const Transform & pose);
void tangoEventReceived(int type, const char * key, const char * value); void tangoEventReceived(int type, const char * key, const char * value);
protected: protected:
@@ -104,34 +66,19 @@ protected:
private: private:
rtabmap::Transform getPoseAtTimestamp(double timestamp); rtabmap::Transform getPoseAtTimestamp(double timestamp);
virtual void mainLoopBegin();
virtual void mainLoop();
private: private:
void * tango_config_; void * tango_config_;
Transform previousPose_;
double previousStamp_;
UTimer cameraStartedTime_;
double stampEpochOffset_;
bool colorCamera_; bool colorCamera_;
int decimation_; int decimation_;
bool rawScanPublished_; bool rawScanPublished_;
bool smoothing_; SensorData data_;
cv::Mat cloud_;
double cloudStamp_;
cv::Mat tangoColor_; cv::Mat tangoColor_;
int tangoColorType_; int tangoColorType_;
double tangoColorStamp_; double tangoColorStamp_;
boost::mutex dataMutex_; boost::mutex dataMutex_;
USemaphore dataReady_; USemaphore dataReady_;
CameraModel model_;
Transform deviceTColorCamera_;
TangoSupportRotation colorCameraToDisplayRotation_;
cv::Mat fisheyeRectifyMapX_; cv::Mat fisheyeRectifyMapX_;
cv::Mat fisheyeRectifyMapY_; cv::Mat fisheyeRectifyMapY_;
GPS lastKnownGPS_;
Transform originOffset_;
bool originUpdate_;
}; };
} /* namespace rtabmap */ } /* namespace rtabmap */
+32 -1
View File
@@ -11,7 +11,9 @@
#include <rtabmap/core/ProgressState.h> #include <rtabmap/core/ProgressState.h>
#include <rtabmap/utilite/ULogger.h> #include <rtabmap/utilite/ULogger.h>
#include <rtabmap/utilite/UEventsManager.h> #include <rtabmap/utilite/UEventsManager.h>
#ifdef __ANDROID__
#include <jni.h> #include <jni.h>
#endif
namespace rtabmap { namespace rtabmap {
@@ -27,16 +29,29 @@ public:
class ProgressionStatus: public ProgressState, public UEventsHandler class ProgressionStatus: public ProgressState, public UEventsHandler
{ {
public: public:
ProgressionStatus() : count_(0), max_(100), jvm_(0), rtabmap_(0) ProgressionStatus() : count_(0), max_(100)
#ifdef __ANDROID__
, jvm_(0), rtabmap_(0)
#else
, swiftClassPtr_(0)
#endif
{ {
registerToEventsManager(); registerToEventsManager();
} }
#ifdef __ANDROID__
void setJavaObjects(JavaVM * jvm, jobject rtabmap) void setJavaObjects(JavaVM * jvm, jobject rtabmap)
{ {
jvm_ = jvm; jvm_ = jvm;
rtabmap_ = rtabmap; rtabmap_ = rtabmap;
} }
#else
void setSwiftCallback(void * classPtr, void(*callback)(void *, int, int))
{
swiftClassPtr_ = classPtr;
swiftCallback = callback;
}
#endif
void reset(int max) void reset(int max)
{ {
@@ -82,6 +97,7 @@ protected:
count_ += ((ProgressEvent*)event)->count_; count_ += ((ProgressEvent*)event)->count_;
// Call JAVA callback // Call JAVA callback
bool success = false; bool success = false;
#ifdef __ANDROID__
if(jvm_ && rtabmap_) if(jvm_ && rtabmap_)
{ {
JNIEnv *env = 0; JNIEnv *env = 0;
@@ -103,6 +119,16 @@ protected:
} }
jvm_->DetachCurrentThread(); jvm_->DetachCurrentThread();
} }
#else // APPLE
if(swiftClassPtr_)
{
std::function<void()> actualCallback = [&](){
swiftCallback(swiftClassPtr_, count_, max_);
};
actualCallback();
success = true;
}
#endif
if(!success) if(!success)
{ {
UERROR("Failed to call rtabmap::updateProgressionCallback"); UERROR("Failed to call rtabmap::updateProgressionCallback");
@@ -114,8 +140,13 @@ protected:
private: private:
int count_; int count_;
int max_; int max_;
#ifdef __ANDROID__
JavaVM *jvm_; JavaVM *jvm_;
jobject rtabmap_; jobject rtabmap_;
#else
void * swiftClassPtr_;
void(*swiftCallback)(void *, int, int);
#endif
}; };
} }
File diff suppressed because it is too large Load Diff
+85 -41
View File
@@ -28,14 +28,15 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#ifndef RTABMAP_APP_H_ #ifndef RTABMAP_APP_H_
#define RTABMAP_APP_H_ #define RTABMAP_APP_H_
#ifdef __ANDROID__
#include <jni.h> #include <jni.h>
#endif
#include <memory> #include <memory>
#include <tango_client_api.h> // NOLINT
#include <tango-gl/util.h> #include <tango-gl/util.h>
#include "scene.h" #include "scene.h"
#include "CameraTango.h" #include "CameraMobile.h"
#include "util.h" #include "util.h"
#include "ProgressionStatus.h" #include "ProgressionStatus.h"
@@ -45,44 +46,43 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include <pcl/pcl_base.h> #include <pcl/pcl_base.h>
#include <pcl/TextureMesh.h> #include <pcl/TextureMesh.h>
// RTABMapApp handles the application lifecycle and resources. // RTABMapApp handles the application lifecycle and resources.
class RTABMapApp : public UEventsHandler { class RTABMapApp : public UEventsHandler {
public: public:
// Constructor and deconstructor. // Constructor and deconstructor.
#ifdef __ANDROID__
RTABMapApp(JNIEnv* env, jobject caller_activity);
#else // __APPLE__
RTABMapApp(); RTABMapApp();
void setupSwiftCallbacks(void * classPtr,
void(*progressCallback)(void *, int, int),
void(*initCallback)(void *, int, const char*),
void(*statsUpdatedCallback)(void *,
int, int, int, int,
float,
int, int, int, int, int ,int,
float,
int,
float,
int,
float, float, float, float,
int, int,
float, float, float, float, float, float));
#endif
~RTABMapApp(); ~RTABMapApp();
void onCreate(JNIEnv* env, jobject caller_activity);
void setScreenRotation(int displayRotation, int cameraRotation); void setScreenRotation(int displayRotation, int cameraRotation);
int openDatabase(const std::string & databasePath, bool databaseInMemory, bool optimize, const std::string & databaseSource=std::string()); int openDatabase(const std::string & databasePath, bool databaseInMemory, bool optimize, bool clearDatabase);
bool onTangoServiceConnected(JNIEnv* env, jobject iBinder);
// Explicitly reset motion tracking and restart the pipeline.
// Note that this will cause motion tracking to re-initialize.
void TangoResetMotionTracking();
// Tango Service point cloud callback function for depth data. Called when new
// new point cloud data is available from the Tango Service.
//
// @param pose: The current point cloud returned by the service,
// caller allocated.
void onPointCloudAvailable(const TangoXYZij* xyz_ij);
// Tango service pose callback function for pose data. Called when new
// information about device pose is available from the Tango Service.
//
// @param pose: The current pose returned by the service, caller allocated.
void onPoseAvailable(const TangoPoseData* pose);
// Tango service event callback function for event data. Called when new events
// are available from the Tango Service.
//
// @param event: Tango event, caller allocated.
void onTangoEventAvailable(const TangoEvent* event);
bool isBuiltWith(int cameraDriver) const;
#ifdef __ANDROID__
bool startCamera(JNIEnv* env, jobject iBinder, jobject context, jobject activity, int driver);
#else // __APPLE__
bool startCamera();
#endif
// Allocate OpenGL resources for rendering, mainly for initializing the Scene. // Allocate OpenGL resources for rendering, mainly for initializing the Scene.
void InitializeGLContent(); void InitializeGLContent();
@@ -92,8 +92,7 @@ class RTABMapApp : public UEventsHandler {
// Main render loop. // Main render loop.
int Render(); int Render();
// Release all non-OpenGL allocated resources. void stopCamera();
void onPause();
// Set render camera's viewing angle, first person, third person or top down. // Set render camera's viewing angle, first person, third person or top down.
// //
@@ -135,22 +134,26 @@ class RTABMapApp : public UEventsHandler {
void setCameraColor(bool enabled); void setCameraColor(bool enabled);
void setFullResolution(bool enabled); void setFullResolution(bool enabled);
void setSmoothing(bool enabled); void setSmoothing(bool enabled);
void setDepthFromMotion(bool enabled);
void setAppendMode(bool enabled); void setAppendMode(bool enabled);
void setDataRecorderMode(bool enabled); void setDataRecorderMode(bool enabled);
void setMaxCloudDepth(float value); void setMaxCloudDepth(float value);
void setMinCloudDepth(float value); void setMinCloudDepth(float value);
void setCloudDensityLevel(int value); void setCloudDensityLevel(int value);
void setMeshAngleTolerance(float value); void setMeshAngleTolerance(float value);
void setMeshDecimationFactor(float value);
void setMeshTriangleSize(int value); void setMeshTriangleSize(int value);
void setClusterRatio(float value); void setClusterRatio(float value);
void setMaxGainRadius(float value); void setMaxGainRadius(float value);
void setRenderingTextureDecimation(int value); void setRenderingTextureDecimation(int value);
void setBackgroundColor(float gray); void setBackgroundColor(float gray);
void setDepthConfidence(int value);
int setMappingParameter(const std::string & key, const std::string & value); int setMappingParameter(const std::string & key, const std::string & value);
void setGPS(const rtabmap::GPS & gps); void setGPS(const rtabmap::GPS & gps);
void addEnvSensor(int type, float value);
void resetMapping();
void save(const std::string & databasePath); void save(const std::string & databasePath);
bool recover(const std::string & from, const std::string & to);
void cancelProcessing(); void cancelProcessing();
bool exportMesh( bool exportMesh(
float cloudVoxelSize, float cloudVoxelSize,
@@ -173,21 +176,42 @@ class RTABMapApp : public UEventsHandler {
bool writeExportedMesh(const std::string & directory, const std::string & name); bool writeExportedMesh(const std::string & directory, const std::string & name);
int postProcessing(int approach); int postProcessing(int approach);
void postCameraPoseEvent(
float x, float y, float z, float qx, float qy, float qz, float qw, double stamp);
void postOdometryEvent(
rtabmap::Transform pose,
float rgb_fx, float rgb_fy, float rgb_cx, float rgb_cy,
float depth_fx, float depth_fy, float depth_cx, float depth_cy,
const rtabmap::Transform & rgbFrame,
const rtabmap::Transform & depthFrame,
double stamp,
double depthStamp,
const void * yPlane, const void * uPlane, const void * vPlane, int yPlaneLen, int rgbWidth, int rgbHeight, int rgbFormat,
const void * depth, int depthLen, int depthWidth, int depthHeight, int depthFormat,
const void * conf, int confLen, int confWidth, int confHeight, int confFormat,
const float * points, int pointsLen, int pointsChannels,
const rtabmap::Transform & viewMatrix, //view matrix
float p00, float p11, float p02, float p12, float p22, float p32, float p23, // projection matrix
float t0, float t1, float t2, float t3, float t4, float t5, float t6, float t7); // tex coord
protected: protected:
virtual bool handleEvent(UEvent * event); virtual bool handleEvent(UEvent * event);
private: private:
int updateMeshDecimation(int width, int height);
rtabmap::ParametersMap getRtabmapParameters(); rtabmap::ParametersMap getRtabmapParameters();
bool smoothMesh(int id, Mesh & mesh); bool smoothMesh(int id, rtabmap::Mesh & mesh);
void gainCompensation(bool full = false); void gainCompensation(bool full = false);
std::vector<pcl::Vertices> filterOrganizedPolygons(const std::vector<pcl::Vertices> & polygons, int cloudSize) const; std::vector<pcl::Vertices> filterOrganizedPolygons(const std::vector<pcl::Vertices> & polygons, int cloudSize) const;
std::vector<pcl::Vertices> filterPolygons(const std::vector<pcl::Vertices> & polygons, int cloudSize) const; std::vector<pcl::Vertices> filterPolygons(const std::vector<pcl::Vertices> & polygons, int cloudSize) const;
private: private:
rtabmap::CameraTango * camera_; int cameraDriver_;
rtabmap::CameraMobile * camera_;
rtabmap::RtabmapThread * rtabmapThread_; rtabmap::RtabmapThread * rtabmapThread_;
rtabmap::Rtabmap * rtabmap_; rtabmap::Rtabmap * rtabmap_;
LogHandler * logHandler_; rtabmap::LogHandler * logHandler_;
bool odomCloudShown_; bool odomCloudShown_;
bool graphOptimization_; bool graphOptimization_;
@@ -196,6 +220,7 @@ class RTABMapApp : public UEventsHandler {
bool trajectoryMode_; bool trajectoryMode_;
bool rawScanSaved_; bool rawScanSaved_;
bool smoothing_; bool smoothing_;
bool depthFromMotion_;
bool cameraColor_; bool cameraColor_;
bool fullResolution_; bool fullResolution_;
bool appendMode_; bool appendMode_;
@@ -204,14 +229,15 @@ class RTABMapApp : public UEventsHandler {
int cloudDensityLevel_; int cloudDensityLevel_;
int meshTrianglePix_; int meshTrianglePix_;
float meshAngleToleranceDeg_; float meshAngleToleranceDeg_;
float meshDecimationFactor_;
float clusterRatio_; float clusterRatio_;
float maxGainRadius_; float maxGainRadius_;
int renderingTextureDecimation_; int renderingTextureDecimation_;
float backgroundColor_; float backgroundColor_;
int depthConfidence_;
rtabmap::ParametersMap mappingParameters_; rtabmap::ParametersMap mappingParameters_;
bool paused_;
bool dataRecorderMode_; bool dataRecorderMode_;
bool clearSceneOnNextRender_; bool clearSceneOnNextRender_;
bool openingDatabase_; bool openingDatabase_;
@@ -222,7 +248,6 @@ class RTABMapApp : public UEventsHandler {
bool bilateralFilteringOnNextRender_; bool bilateralFilteringOnNextRender_;
bool takeScreenshotOnNextRender_; bool takeScreenshotOnNextRender_;
bool cameraJustInitialized_; bool cameraJustInitialized_;
int meshDecimation_;
int totalPoints_; int totalPoints_;
int totalPolygons_; int totalPolygons_;
int lastDrawnCloudsCount_; int lastDrawnCloudsCount_;
@@ -241,16 +266,18 @@ class RTABMapApp : public UEventsHandler {
// 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.
Scene main_scene_; Scene main_scene_;
UTimer fpsTime_;
std::list<rtabmap::RtabmapEvent*> rtabmapEvents_; std::list<rtabmap::RtabmapEvent*> rtabmapEvents_;
std::list<rtabmap::RtabmapEvent*> visLocalizationEvents_;
std::list<rtabmap::OdometryEvent> odomEvents_; std::list<rtabmap::OdometryEvent> odomEvents_;
std::list<rtabmap::Transform> poseEvents_; std::list<rtabmap::Transform> poseEvents_;
std::map<double, rtabmap::Transform> poseBuffer_;
rtabmap::Transform mapToOdom_; rtabmap::Transform mapToOdom_;
boost::mutex cameraMutex_;
boost::mutex rtabmapMutex_; boost::mutex rtabmapMutex_;
boost::mutex visLocalizationMutex_;
boost::mutex meshesMutex_; boost::mutex meshesMutex_;
boost::mutex odomMutex_; boost::mutex odomMutex_;
boost::mutex poseMutex_; boost::mutex poseMutex_;
@@ -258,12 +285,29 @@ class RTABMapApp : public UEventsHandler {
USemaphore screenshotReady_; USemaphore screenshotReady_;
std::map<int, Mesh> createdMeshes_; std::map<int, rtabmap::Mesh> createdMeshes_;
std::map<int, rtabmap::Transform> rawPoses_; std::map<int, rtabmap::Transform> rawPoses_;
std::pair<rtabmap::RtabmapEventInit::Status, std::string> status_; std::pair<rtabmap::RtabmapEventInit::Status, std::string> status_;
rtabmap::ProgressionStatus progressionStatus_; rtabmap::ProgressionStatus progressionStatus_;
#ifndef __ANDROID__
void * swiftClassPtr_;
void(*swiftInitCallback)(void *, int, const char *);
void(*swiftStatsUpdatedCallback)(void *,
int, int, int, int,
float,
int, int, int, int, int ,int,
float,
int,
float,
int,
float, float, float, float,
int, int,
float, float, float, float, float, float);
#endif
}; };
#endif // TANGO_POINT_CLOUD_POINT_CLOUD_APP_H_ #endif // TANGO_POINT_CLOUD_POINT_CLOUD_APP_H_
+210
View File
@@ -0,0 +1,210 @@
/*
* Copyright 2018 Google Inc. All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
// This modules handles drawing the passthrough camera image into the OpenGL
// scene.
#include "background_renderer.h"
#include <type_traits>
namespace {
const std::string kVertexShader =
"attribute vec4 a_Position;\n"
"attribute vec2 a_TexCoord;\n"
"varying vec2 v_TexCoord;\n"
"void main() {\n"
" gl_Position = a_Position;\n"
" v_TexCoord = a_TexCoord;\n"
"}\n";
const std::string kFragmentShaderOES =
"#extension GL_OES_EGL_image_external : require\n"
"precision mediump float;\n"
"varying vec2 v_TexCoord;\n"
"uniform samplerExternalOES sTexture;\n"
"uniform bool uRedUnknown;\n"
"void main() {\n"
" vec4 sample = texture2D(sTexture, v_TexCoord);\n"
" float grey = 0.21 * sample.r + 0.71 * sample.g + 0.07 * sample.b;\n"
" gl_FragColor = vec4(grey, uRedUnknown?0.0:grey, uRedUnknown?0.0:grey, 0.5);\n"
"}\n";
const std::string kFragmentShaderBlendingOES =
"#extension GL_OES_EGL_image_external : require\n"
"precision mediump float;\n"
"varying vec2 v_TexCoord;\n"
"uniform samplerExternalOES sTexture;\n"
"uniform sampler2D uDepthTexture;\n"
"uniform vec2 uScreenScale;\n"
"uniform bool uRedUnknown;\n"
"void main() {\n"
" vec4 sample = texture2D(sTexture, v_TexCoord);\n"
" vec2 coord = uScreenScale * gl_FragCoord.xy;\n;"
" vec4 depthPacked = texture2D(uDepthTexture, coord);\n"
" float depth = dot(depthPacked, 1./vec4(1.,255.,65025.,16581375.));\n"
" if(depth > 0.0)\n"
" gl_FragColor = vec4(sample.r, sample.g, sample.b, 0.5);\n"
" else {\n"
" float grey = 0.21 * sample.r + 0.71 * sample.g + 0.07 * sample.b;\n"
" gl_FragColor = vec4(grey, uRedUnknown?0.0:grey, uRedUnknown?0.0:grey, 0.5);\n"
" }\n"
"}\n";
const std::string kFragmentShader =
"precision mediump float;\n"
"varying vec2 v_TexCoord;\n"
"uniform sampler2D sTexture;\n"
"uniform bool uRedUnknown;\n"
"void main() {\n"
" vec4 sample = texture2D(sTexture, v_TexCoord);\n"
" float grey = 0.21 * sample.r + 0.71 * sample.g + 0.07 * sample.b;\n"
" gl_FragColor = vec4(grey, uRedUnknown?0.0:grey, uRedUnknown?0.0:grey, 0.5);\n"
"}\n";
const std::string kFragmentShaderBlending =
"precision mediump float;\n"
"varying vec2 v_TexCoord;\n"
"uniform sampler2D sTexture;\n"
"uniform sampler2D uDepthTexture;\n"
"uniform vec2 uScreenScale;\n"
"uniform bool uRedUnknown;\n"
"void main() {\n"
" vec4 sample = texture2D(sTexture, v_TexCoord);\n"
" vec2 coord = uScreenScale * gl_FragCoord.xy;\n;"
" vec4 depthPacked = texture2D(uDepthTexture, coord);\n"
" float depth = dot(depthPacked, 1./vec4(1.,255.,65025.,16581375.));\n"
" if(depth > 0.0)\n"
" gl_FragColor = vec4(sample.r, sample.g, sample.b, 0.5);\n"
" else {\n"
" float grey = 0.21 * sample.r + 0.71 * sample.g + 0.07 * sample.b;\n"
" gl_FragColor = vec4(grey, uRedUnknown?0.0:grey, uRedUnknown?0.0:grey, 0.5);\n"
" }\n"
"}\n";
/* To debug depth texture
const std::string kFragmentShader =
"precision mediump float;\n"
"varying vec2 v_TexCoord;\n"
"uniform sampler2D sTexture;\n"
"void main() {\n"
" float uNearZ = 0.2;\n"
" float uFarZ = 1000.0;\n"
" float depth = texture2D(sTexture, v_TexCoord).r;\n"
" float num = (2.0 * uNearZ * uFarZ);\n"
" float diff = (uFarZ - uNearZ);\n"
" float add = (uFarZ + uNearZ);\n"
" float ndcDepth = depth * 2.0 - 1.0;\n" // Back to NDC
" float linearDepth = num / (add - ndcDepth * diff);\n" // inverse projection matrix
" float grey = linearDepth/3.0;\n"
" gl_FragColor = vec4(grey, grey, grey, 0.5);\n"
"}\n";
*/
} // namespace
std::vector<GLuint> BackgroundRenderer::shaderPrograms_;
BackgroundRenderer::~BackgroundRenderer()
{
for(unsigned int i=0; i<shaderPrograms_.size(); ++i)
{
glDeleteShader(shaderPrograms_[i]);
}
shaderPrograms_.clear();
}
void BackgroundRenderer::InitializeGlContent(GLuint textureId, bool oes)
{
LOGI("textureId=%d", textureId);
texture_id_ = textureId;
#ifdef __ANDROID__
oes_ = oes;
#endif
if(shaderPrograms_.empty())
{
shaderPrograms_.resize(2,0);
shaderPrograms_[0] = tango_gl::util::CreateProgram(
kVertexShader.c_str(),
oes_?kFragmentShaderOES.c_str():kFragmentShader.c_str());
UASSERT(shaderPrograms_[0]!=0);
shaderPrograms_[1] = tango_gl::util::CreateProgram(
kVertexShader.c_str(),
oes_?kFragmentShaderBlendingOES.c_str():kFragmentShaderBlending.c_str());
UASSERT(shaderPrograms_[1]!=0);
}
}
void BackgroundRenderer::Draw(const float * transformed_uvs, const GLuint & depthTexture, int screenWidth, int screenHeight, bool redUnknown) {
static_assert(std::extent<decltype(BackgroundRenderer_kVertices)>::value == kNumVertices * 2, "Incorrect kVertices length");
GLuint program = shaderPrograms_[depthTexture>0?1:0];
glUseProgram(program);
glDepthMask(GL_FALSE);
glEnable (GL_BLEND);
glActiveTexture(GL_TEXTURE0);
#ifdef __ANDROID__
if(oes_)
glBindTexture(GL_TEXTURE_EXTERNAL_OES, texture_id_);
else
#endif
glBindTexture(GL_TEXTURE_2D, texture_id_);
if(depthTexture>0)
{
// Texture activate unit 1
glActiveTexture(GL_TEXTURE1);
// Bind the texture to this unit.
glBindTexture(GL_TEXTURE_2D, depthTexture);
// Tell the texture uniform sampler to use this texture in the shader by binding to texture unit 1.
GLuint depth_texture_handle = glGetUniformLocation(program, "uDepthTexture");
glUniform1i(depth_texture_handle, 1);
GLuint screenScale_handle = glGetUniformLocation(program, "uScreenScale");
glUniform2f(screenScale_handle, 1.0f/(float)screenWidth, 1.0f/(float)screenHeight);
}
GLuint screenScale_handle = glGetUniformLocation(program, "uRedUnknown");
glUniform1i(screenScale_handle, redUnknown);
GLuint attributeVertices = glGetAttribLocation(program, "a_Position");
GLuint attributeUvs = glGetAttribLocation(program, "a_TexCoord");
glVertexAttribPointer(attributeVertices, 2, GL_FLOAT, GL_FALSE, 0, BackgroundRenderer_kVertices);
glVertexAttribPointer(attributeUvs, 2, GL_FLOAT, GL_FALSE, 0, transformed_uvs?transformed_uvs:BackgroundRenderer_kTexCoord);
glEnableVertexAttribArray(attributeVertices);
glEnableVertexAttribArray(attributeUvs);
glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
glDisableVertexAttribArray(attributeVertices);
glDisableVertexAttribArray(attributeUvs);
glUseProgram(0);
glDepthMask(GL_TRUE);
glDisable (GL_BLEND);
tango_gl::util::CheckGlError("BackgroundRenderer::Draw() error");
}
+70
View File
@@ -0,0 +1,70 @@
/*
* Copyright 2018 Google Inc. All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef C_ARCORE_AUGMENTED_IMAGE_BACKGROUND_RENDERER_H_
#define C_ARCORE_AUGMENTED_IMAGE_BACKGROUND_RENDERER_H_
#ifdef __ANDROID__
#include <GLES2/gl2.h>
#include <GLES2/gl2ext.h>
#else // __APPLE__
#include <OpenGLES/ES2/gl.h>
#include <OpenGLES/ES2/glext.h>
#endif
#include <cstdlib>
#include "util.h"
static const GLfloat BackgroundRenderer_kVertices[] = {
-1.0f, -1.0f, +1.0f, -1.0f, -1.0f, +1.0f, +1.0f, +1.0f,
};
static const GLfloat BackgroundRenderer_kTexCoord[] = {
1.0f, 1.0f, 1.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f,
};
//android phone
//11 10 01 00 // portrait
//01 11 00 10 // left
//10 00 11 01 // right
//00 01 10 11 // down
// This class renders the passthrough camera image into the OpenGL frame.
class BackgroundRenderer {
public:
// Positions of the quad vertices in clip space (X, Y).
static constexpr int kNumVertices = 4;
public:
BackgroundRenderer() = default;
~BackgroundRenderer();
// Sets up OpenGL state. Must be called on the OpenGL thread and before any
// other methods below.
void InitializeGlContent(GLuint textureId, bool oes);
// Draws the background image. This methods must be called for every ArFrame
// returned by ArSession_update() to catch display geometry change events.
void Draw(const float * transformed_uvs, const GLuint & depthTexture, int screenWidth, int screenHeight, bool redUnknown);
private:
static std::vector<GLuint> shaderPrograms_;
GLuint texture_id_;
bool oes_ = false;
};
#endif // C_ARCORE_AUGMENTED_IMAGE_BACKGROUND_RENDERER_H_
+4
View File
@@ -31,7 +31,11 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include "rtabmap/utilite/ULogger.h" #include "rtabmap/utilite/ULogger.h"
#include "util.h" #include "util.h"
#ifdef __ANDROID__
#include <GLES2/gl2.h> #include <GLES2/gl2.h>
#else //__APPLE__
#include <OpenGLES/ES2/gl.h>
#endif
GraphDrawable::GraphDrawable( GraphDrawable::GraphDrawable(
GLuint shaderProgram, GLuint shaderProgram,
+2 -1
View File
@@ -28,8 +28,9 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#ifndef GRAPH_DRAWABLE_H_ #ifndef GRAPH_DRAWABLE_H_
#define GRAPH_DRAWABLE_H_ #define GRAPH_DRAWABLE_H_
#ifdef __ANDROID__
#include <jni.h> #include <jni.h>
#endif
#include <tango-gl/util.h> #include <tango-gl/util.h>
#include <vector> #include <vector>
#include <pcl/point_cloud.h> #include <pcl/point_cloud.h>
File diff suppressed because it is too large Load Diff
+278 -151
View File
@@ -35,7 +35,11 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include "util.h" #include "util.h"
#include "pcl/common/transforms.h" #include "pcl/common/transforms.h"
#ifdef __ANDROID__
#include <GLES2/gl2.h> #include <GLES2/gl2.h>
#else // __APPLE__
#include <OpenGLES/ES2/gl.h>
#endif
#define LOW_DEC 2 #define LOW_DEC 2
#define LOWLOW_DEC 4 #define LOWLOW_DEC 4
@@ -57,7 +61,7 @@ enum PointCloudShaders
// PointCloud shaders // PointCloud shaders
const std::string kPointCloudVertexShader = const std::string kPointCloudVertexShader =
"precision mediump float;\n" "precision highp float;\n"
"precision mediump int;\n" "precision mediump int;\n"
"attribute vec3 aVertex;\n" "attribute vec3 aVertex;\n"
"attribute vec3 aColor;\n" "attribute vec3 aColor;\n"
@@ -75,7 +79,7 @@ const std::string kPointCloudVertexShader =
" vColor = aColor;\n" " vColor = aColor;\n"
"}\n"; "}\n";
const std::string kPointCloudLightingVertexShader = const std::string kPointCloudLightingVertexShader =
"precision mediump float;\n" "precision highp float;\n"
"precision mediump int;\n" "precision mediump int;\n"
"attribute vec3 aVertex;\n" "attribute vec3 aVertex;\n"
"attribute vec3 aNormal;\n" "attribute vec3 aNormal;\n"
@@ -100,7 +104,7 @@ const std::string kPointCloudLightingVertexShader =
"}\n"; "}\n";
const std::string kPointCloudFragmentShader = const std::string kPointCloudFragmentShader =
"precision mediump float;\n" "precision highp float;\n"
"precision mediump int;\n" "precision mediump int;\n"
"uniform float uGainR;\n" "uniform float uGainR;\n"
"uniform float uGainG;\n" "uniform float uGainG;\n"
@@ -127,7 +131,8 @@ const std::string kPointCloudBlendingFragmentShader =
" vec4 textureColor = vec4(vColor.z, vColor.y, vColor.x, 1.0);\n" " vec4 textureColor = vec4(vColor.z, vColor.y, vColor.x, 1.0);\n"
" float alpha = 1.0;\n" " float alpha = 1.0;\n"
" vec2 coord = uScreenScale * gl_FragCoord.xy;\n;" " vec2 coord = uScreenScale * gl_FragCoord.xy;\n;"
" float depth = texture2D(uDepthTexture, coord).r;\n" " vec4 depthPacked = texture2D(uDepthTexture, coord);\n"
" float depth = dot(depthPacked, 1./vec4(1.,255.,65025.,16581375.));\n"
" float num = (2.0 * uNearZ * uFarZ);\n" " float num = (2.0 * uNearZ * uFarZ);\n"
" float diff = (uFarZ - uNearZ);\n" " float diff = (uFarZ - uNearZ);\n"
" float add = (uFarZ + uNearZ);\n" " float add = (uFarZ + uNearZ);\n"
@@ -141,7 +146,7 @@ const std::string kPointCloudBlendingFragmentShader =
"}\n"; "}\n";
const std::string kPointCloudDepthPackingVertexShader = const std::string kPointCloudDepthPackingVertexShader =
"precision mediump float;\n" "precision highp float;\n"
"precision mediump int;\n" "precision mediump int;\n"
"attribute vec3 aVertex;\n" "attribute vec3 aVertex;\n"
"uniform mat4 uMVP;\n" "uniform mat4 uMVP;\n"
@@ -154,15 +159,15 @@ const std::string kPointCloudDepthPackingFragmentShader =
"precision highp float;\n" "precision highp float;\n"
"precision mediump int;\n" "precision mediump int;\n"
"void main() {\n" "void main() {\n"
" float toFixed = 255.0/256.0;\n" " vec4 enc = vec4(1.,255.,65025.,16581375.) * gl_FragCoord.z;\n"
" vec4 enc = vec4(1.0, 255.0, 65025.0, 160581375.0) * toFixed * gl_FragCoord.z;\n"
" enc = fract(enc);\n" " enc = fract(enc);\n"
" enc -= enc.yzww * vec2(1./255., 0.).xxxy;\n"
" gl_FragColor = enc;\n" " gl_FragColor = enc;\n"
"}\n"; "}\n";
// Texture shaders // Texture shaders
const std::string kTextureMeshVertexShader = const std::string kTextureMeshVertexShader =
"precision mediump float;\n" "precision highp float;\n"
"precision mediump int;\n" "precision mediump int;\n"
"attribute vec3 aVertex;\n" "attribute vec3 aVertex;\n"
"attribute vec2 aTexCoord;\n" "attribute vec2 aTexCoord;\n"
@@ -185,7 +190,7 @@ const std::string kTextureMeshVertexShader =
" vLightWeighting = 1.0;\n" " vLightWeighting = 1.0;\n"
"}\n"; "}\n";
const std::string kTextureMeshLightingVertexShader = const std::string kTextureMeshLightingVertexShader =
"precision mediump float;\n" "precision highp float;\n"
"precision mediump int;\n" "precision mediump int;\n"
"attribute vec3 aVertex;\n" "attribute vec3 aVertex;\n"
"attribute vec3 aNormal;\n" "attribute vec3 aNormal;\n"
@@ -214,7 +219,7 @@ const std::string kTextureMeshLightingVertexShader =
" vLightWeighting=0.5;\n" " vLightWeighting=0.5;\n"
"}\n"; "}\n";
const std::string kTextureMeshFragmentShader = const std::string kTextureMeshFragmentShader =
"precision mediump float;\n" "precision highp float;\n"
"precision mediump int;\n" "precision mediump int;\n"
"uniform sampler2D uTexture;\n" "uniform sampler2D uTexture;\n"
"uniform float uGainR;\n" "uniform float uGainR;\n"
@@ -245,7 +250,8 @@ const std::string kTextureMeshBlendingFragmentShader =
" vec4 textureColor = texture2D(uTexture, vTexCoord);\n" " vec4 textureColor = texture2D(uTexture, vTexCoord);\n"
" float alpha = 1.0;\n" " float alpha = 1.0;\n"
" vec2 coord = uScreenScale * gl_FragCoord.xy;\n;" " vec2 coord = uScreenScale * gl_FragCoord.xy;\n;"
" float depth = texture2D(uDepthTexture, coord).r;\n" " vec4 depthPacked = texture2D(uDepthTexture, coord);\n"
" float depth = dot(depthPacked, 1./vec4(1.,255.,65025.,16581375.));\n"
" float num = (2.0 * uNearZ * uFarZ);\n" " float num = (2.0 * uNearZ * uFarZ);\n"
" float diff = (uFarZ - uNearZ);\n" " float diff = (uFarZ - uNearZ);\n"
" float add = (uFarZ + uNearZ);\n" " float add = (uFarZ + uNearZ);\n"
@@ -255,7 +261,7 @@ const std::string kTextureMeshBlendingFragmentShader =
" float linearFragz = num / (add - ndcFragz * diff);\n" // inverse projection matrix " float linearFragz = num / (add - ndcFragz * diff);\n" // inverse projection matrix
" if(linearFragz > linearDepth + 0.05)\n" " if(linearFragz > linearDepth + 0.05)\n"
" alpha=0.0;\n" " alpha=0.0;\n"
" gl_FragColor = vec4(textureColor.r * uGainR * vLightWeighting, textureColor.g * uGainG * vLightWeighting, textureColor.b * uGainB * vLightWeighting, alpha);\n" " gl_FragColor = vec4(textureColor.r * uGainR * vLightWeighting, textureColor.g * uGainG * vLightWeighting, textureColor.b * uGainB * vLightWeighting, alpha);\n"
"}\n"; "}\n";
std::vector<GLuint> PointCloudDrawable::shaderPrograms_; std::vector<GLuint> PointCloudDrawable::shaderPrograms_;
@@ -303,8 +309,8 @@ PointCloudDrawable::PointCloudDrawable(
float gainR, float gainR,
float gainG, float gainG,
float gainB) : float gainB) :
vertex_buffers_(0), vertex_buffer_(0),
textures_(0), texture_(0),
nPoints_(0), nPoints_(0),
pose_(rtabmap::Transform::getIdentity()), pose_(rtabmap::Transform::getIdentity()),
poseGl_(1.0f), poseGl_(1.0f),
@@ -314,14 +320,16 @@ PointCloudDrawable::PointCloudDrawable(
gainG_(gainG), gainG_(gainG),
gainB_(gainB) gainB_(gainB)
{ {
index_buffers_.resize(6, 0);
index_buffers_count_.resize(6, 0);
updateCloud(cloud, indices); updateCloud(cloud, indices);
} }
PointCloudDrawable::PointCloudDrawable( PointCloudDrawable::PointCloudDrawable(
const Mesh & mesh, const rtabmap::Mesh & mesh,
bool createWireframe) : bool createWireframe) :
vertex_buffers_(0), vertex_buffer_(0),
textures_(0), texture_(0),
nPoints_(0), nPoints_(0),
pose_(rtabmap::Transform::getIdentity()), pose_(rtabmap::Transform::getIdentity()),
poseGl_(1.0f), poseGl_(1.0f),
@@ -331,64 +339,83 @@ PointCloudDrawable::PointCloudDrawable(
gainG_(1.0f), gainG_(1.0f),
gainB_(1.0f) gainB_(1.0f)
{ {
index_buffers_.resize(6, 0);
index_buffers_count_.resize(6, 0);
updateMesh(mesh, createWireframe); updateMesh(mesh, createWireframe);
} }
PointCloudDrawable::~PointCloudDrawable() PointCloudDrawable::~PointCloudDrawable()
{ {
LOGI("Freeing cloud buffer %d", vertex_buffers_); LOGI("Freeing cloud buffer %d", vertex_buffer_);
if (vertex_buffers_) if (vertex_buffer_)
{ {
glDeleteBuffers(1, &vertex_buffers_); glDeleteBuffers(1, &vertex_buffer_);
tango_gl::util::CheckGlError("PointCloudDrawable::~PointCloudDrawable()"); tango_gl::util::CheckGlError("PointCloudDrawable::~PointCloudDrawable()");
vertex_buffers_ = 0; vertex_buffer_ = 0;
} }
if (textures_) if (texture_)
{ {
glDeleteTextures(1, &textures_); glDeleteTextures(1, &texture_);
tango_gl::util::CheckGlError("PointCloudDrawable::~PointCloudDrawable()"); tango_gl::util::CheckGlError("PointCloudDrawable::~PointCloudDrawable()");
textures_ = 0; texture_ = 0;
} }
for(size_t i=0; i<index_buffers_.size(); ++i)
{
if(index_buffers_[i])
{
glDeleteBuffers(1, &index_buffers_[i]);
index_buffers_[i] = 0;
tango_gl::util::CheckGlError("PointCloudDrawable::~PointCloudDrawable()");
}
}
} }
void PointCloudDrawable::updatePolygons(const std::vector<pcl::Vertices> & polygons, const std::vector<pcl::Vertices> & polygonsLowRes, bool createWireframe) void PointCloudDrawable::updatePolygons(const std::vector<pcl::Vertices> & polygons, const std::vector<pcl::Vertices> & polygonsLowRes, bool createWireframe)
{ {
LOGD("Update polygons"); for(int i=0; i<4; ++i)
polygons_.clear(); {
polygonLines_.clear(); if(index_buffers_[i])
polygonsLowRes_.clear(); {
polygonLinesLowRes_.clear(); glDeleteBuffers(1, &index_buffers_[i]);
index_buffers_[i] = 0;
tango_gl::util::CheckGlError("PointCloudDrawable::updatePolygons() clearing polygon buffers");
}
}
//LOGD("Update polygons");
if(polygons.size() && organizedToDenseIndices_.size()) if(polygons.size() && organizedToDenseIndices_.size())
{ {
unsigned int polygonSize = polygons[0].vertices.size(); size_t polygonSize = polygons[0].vertices.size();
UASSERT(polygonSize == 3); UASSERT(polygonSize == 3);
polygons_.resize(polygons.size() * polygonSize); std::vector<std::vector<GLuint> > indexes(4);
indexes[0].resize(polygons.size() * polygonSize);
if(createWireframe) if(createWireframe)
polygonLines_.resize(polygons_.size()*2); indexes[2].resize(indexes[0].size()*2);
int oi = 0; int oi = 0;
int li = 0; int li = 0;
for(unsigned int i=0; i<polygons.size(); ++i) for(size_t i=0; i<polygons.size(); ++i)
{ {
UASSERT(polygons[i].vertices.size() == polygonSize); UASSERT(polygons[i].vertices.size() == polygonSize);
for(unsigned int j=0; j<polygonSize; ++j) for(unsigned int j=0; j<polygonSize; ++j)
{ {
polygons_[oi++] = organizedToDenseIndices_.at(polygons[i].vertices[j]); indexes[0][oi++] = organizedToDenseIndices_.at(polygons[i].vertices[j]);
if(createWireframe) if(createWireframe)
{ {
polygonLines_[li++] = organizedToDenseIndices_.at(polygons[i].vertices[j]); indexes[2][li++] = organizedToDenseIndices_.at(polygons[i].vertices[j]);
polygonLines_[li++] = organizedToDenseIndices_.at(polygons[i].vertices[(j+1) % polygonSize]); indexes[2][li++] = organizedToDenseIndices_.at(polygons[i].vertices[(j+1) % polygonSize]);
} }
} }
} }
if(polygonsLowRes.size()) if(polygonsLowRes.size())
{ {
unsigned int polygonSize = polygonsLowRes[0].vertices.size(); size_t polygonSize = polygonsLowRes[0].vertices.size();
UASSERT(polygonSize == 3); UASSERT(polygonSize == 3);
polygonsLowRes_.resize(polygonsLowRes.size() * polygonSize); indexes[1].resize(polygonsLowRes.size() * polygonSize);
if(createWireframe) if(createWireframe)
polygonLinesLowRes_.resize(polygonsLowRes_.size()*2); indexes[3].resize(indexes[1].size()*2);
int oi = 0; int oi = 0;
int li = 0; int li = 0;
for(unsigned int i=0; i<polygonsLowRes.size(); ++i) for(unsigned int i=0; i<polygonsLowRes.size(); ++i)
@@ -396,15 +423,44 @@ void PointCloudDrawable::updatePolygons(const std::vector<pcl::Vertices> & polyg
UASSERT(polygonsLowRes[i].vertices.size() == polygonSize); UASSERT(polygonsLowRes[i].vertices.size() == polygonSize);
for(unsigned int j=0; j<polygonSize; ++j) for(unsigned int j=0; j<polygonSize; ++j)
{ {
polygonsLowRes_[oi++] = organizedToDenseIndices_.at(polygonsLowRes[i].vertices[j]); indexes[1][oi++] = organizedToDenseIndices_.at(polygonsLowRes[i].vertices[j]);
if(createWireframe) if(createWireframe)
{ {
polygonLinesLowRes_[li++] = organizedToDenseIndices_.at(polygonsLowRes[i].vertices[j]); indexes[3][li++] = organizedToDenseIndices_.at(polygonsLowRes[i].vertices[j]);
polygonLinesLowRes_[li++] = organizedToDenseIndices_.at(polygonsLowRes[i].vertices[(j+1)%polygonSize]); indexes[3][li++] = organizedToDenseIndices_.at(polygonsLowRes[i].vertices[(j+1)%polygonSize]);
} }
} }
} }
} }
// Generate index buffers
for(size_t i=0; i<indexes.size(); ++i)
{
if(!indexes[i].empty())
{
glGenBuffers(1, &index_buffers_[i]);
if(!index_buffers_[i])
{
LOGE("OpenGL: could not generate index buffer %ld\n", i);
return;
}
LOGD("Adding polygon index %ld size=%ld", i, indexes[i].size());
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, index_buffers_[i]);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(uint32_t) * indexes[i].size(), indexes[i].data(), GL_STATIC_DRAW);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
index_buffers_count_[i] = (int)indexes[i].size();
GLint error = glGetError();
if(error != GL_NO_ERROR)
{
LOGE("OpenGL: Could not allocate indexes (0x%x)\n", error);
index_buffers_[i] = 0;
return;
}
}
}
} }
} }
@@ -412,43 +468,51 @@ void PointCloudDrawable::updateCloud(const pcl::PointCloud<pcl::PointXYZRGB>::Pt
{ {
UASSERT(cloud.get() && !cloud->empty()); UASSERT(cloud.get() && !cloud->empty());
nPoints_ = 0; nPoints_ = 0;
polygons_.clear();
polygonsLowRes_.clear();
verticesLowRes_.clear();
verticesLowLowRes_.clear();
aabbMinModel_ = aabbMinWorld_ = pcl::PointXYZ(1000,1000,1000); aabbMinModel_ = aabbMinWorld_ = pcl::PointXYZ(1000,1000,1000);
aabbMaxModel_ = aabbMaxWorld_ = pcl::PointXYZ(-1000,-1000,-1000); aabbMaxModel_ = aabbMaxWorld_ = pcl::PointXYZ(-1000,-1000,-1000);
if (vertex_buffers_) if (vertex_buffer_)
{ {
glDeleteBuffers(1, &vertex_buffers_); glDeleteBuffers(1, &vertex_buffer_);
tango_gl::util::CheckGlError("PointCloudDrawable::~PointCloudDrawable()"); tango_gl::util::CheckGlError("PointCloudDrawable::updateCloud() clear vertex buffer");
vertex_buffers_ = 0; vertex_buffer_ = 0;
} }
if (textures_) if (texture_)
{ {
glDeleteTextures(1, &textures_); glDeleteTextures(1, &texture_);
tango_gl::util::CheckGlError("PointCloudDrawable::~PointCloudDrawable()"); tango_gl::util::CheckGlError("PointCloudDrawable::updateCloud() clear texture buffer");
textures_ = 0; texture_ = 0;
} }
for(size_t i=0; i<index_buffers_.size(); ++i)
{
if(index_buffers_[i])
{
glDeleteBuffers(1, &index_buffers_[i]);
index_buffers_[i] = 0;
tango_gl::util::CheckGlError("PointCloudDrawable::updateCloud() clear index buffer");
}
}
glGenBuffers(1, &vertex_buffers_); glGenBuffers(1, &vertex_buffer_);
if(!vertex_buffers_) if(!vertex_buffer_)
{ {
LOGE("OpenGL: could not generate vertex buffers\n"); LOGE("OpenGL: could not generate vertex buffers\n");
return; return;
} }
LOGI("Creating cloud buffer %d", vertex_buffers_); LOGI("Creating cloud buffer %d", vertex_buffer_);
std::vector<float> vertices; std::vector<float> vertices;
int totalPoints = 0; size_t totalPoints = 0;
std::vector<GLuint> verticesLowRes;
std::vector<GLuint> verticesLowLowRes;
if(indices.get() && indices->size()) if(indices.get() && indices->size())
{ {
totalPoints = indices->size(); totalPoints = indices->size();
vertices.resize(indices->size()*4); vertices.resize(indices->size()*4);
verticesLowRes_.resize(cloud->isOrganized()?totalPoints:0); verticesLowRes.resize(cloud->isOrganized()?totalPoints:0);
verticesLowLowRes_.resize(cloud->isOrganized()?totalPoints:0); verticesLowLowRes.resize(cloud->isOrganized()?totalPoints:0);
int oi_low = 0; int oi_low = 0;
int oi_lowlow = 0; int oi_lowlow = 0;
for(unsigned int i=0; i<indices->size(); ++i) for(unsigned int i=0; i<indices->size(); ++i)
@@ -465,23 +529,23 @@ void PointCloudDrawable::updateCloud(const pcl::PointCloud<pcl::PointXYZRGB>::Pt
{ {
if(indices->at(i)%LOW_DEC == 0 && (indices->at(i)/cloud->width) % LOW_DEC == 0) if(indices->at(i)%LOW_DEC == 0 && (indices->at(i)/cloud->width) % LOW_DEC == 0)
{ {
verticesLowRes_[oi_low++] = i; verticesLowRes[oi_low++] = i;
} }
if(indices->at(i)%LOWLOW_DEC == 0 && (indices->at(i)/cloud->width) % LOWLOW_DEC == 0) if(indices->at(i)%LOWLOW_DEC == 0 && (indices->at(i)/cloud->width) % LOWLOW_DEC == 0)
{ {
verticesLowLowRes_[oi_lowlow++] = i; verticesLowLowRes[oi_lowlow++] = i;
} }
} }
} }
verticesLowRes_.resize(oi_low); verticesLowRes.resize(oi_low);
verticesLowLowRes_.resize(oi_lowlow); verticesLowLowRes.resize(oi_lowlow);
} }
else else
{ {
totalPoints = cloud->size(); totalPoints = cloud->size();
vertices.resize(cloud->size()*4); vertices.resize(cloud->size()*4);
verticesLowRes_.resize(cloud->isOrganized()?totalPoints:0); verticesLowRes.resize(cloud->isOrganized()?totalPoints:0);
verticesLowLowRes_.resize(cloud->isOrganized()?totalPoints:0); verticesLowLowRes.resize(cloud->isOrganized()?totalPoints:0);
int oi_low = 0; int oi_low = 0;
int oi_lowlow = 0; int oi_lowlow = 0;
for(unsigned int i=0; i<cloud->size(); ++i) for(unsigned int i=0; i<cloud->size(); ++i)
@@ -498,19 +562,19 @@ void PointCloudDrawable::updateCloud(const pcl::PointCloud<pcl::PointXYZRGB>::Pt
{ {
if(i%LOW_DEC == 0 && (i/cloud->width) % LOW_DEC == 0) if(i%LOW_DEC == 0 && (i/cloud->width) % LOW_DEC == 0)
{ {
verticesLowRes_[oi_low++] = i; verticesLowRes[oi_low++] = i;
} }
if(i%LOWLOW_DEC == 0 && (i/cloud->width) % LOWLOW_DEC == 0) if(i%LOWLOW_DEC == 0 && (i/cloud->width) % LOWLOW_DEC == 0)
{ {
verticesLowLowRes_[oi_lowlow++] = i; verticesLowLowRes[oi_lowlow++] = i;
} }
} }
} }
verticesLowRes_.resize(oi_low); verticesLowRes.resize(oi_low);
verticesLowLowRes_.resize(oi_lowlow); verticesLowLowRes.resize(oi_lowlow);
} }
glBindBuffer(GL_ARRAY_BUFFER, vertex_buffers_); glBindBuffer(GL_ARRAY_BUFFER, vertex_buffer_);
glBufferData(GL_ARRAY_BUFFER, sizeof(GLfloat) * (int)vertices.size(), (const void *)vertices.data(), GL_STATIC_DRAW); glBufferData(GL_ARRAY_BUFFER, sizeof(GLfloat) * (int)vertices.size(), (const void *)vertices.data(), GL_STATIC_DRAW);
glBindBuffer(GL_ARRAY_BUFFER, 0); glBindBuffer(GL_ARRAY_BUFFER, 0);
@@ -518,26 +582,65 @@ void PointCloudDrawable::updateCloud(const pcl::PointCloud<pcl::PointXYZRGB>::Pt
if(error != GL_NO_ERROR) if(error != GL_NO_ERROR)
{ {
LOGE("OpenGL: Could not allocate point cloud (0x%x)\n", error); LOGE("OpenGL: Could not allocate point cloud (0x%x)\n", error);
vertex_buffers_ = 0; vertex_buffer_ = 0;
return; return;
} }
// vertex index buffers
for(size_t i=4; i<5; ++i)
{
if((i==4 && !verticesLowRes.empty()) ||
(i==5 && !verticesLowLowRes.empty()))
{
glGenBuffers(1, &index_buffers_[i]);
if(!index_buffers_[i])
{
LOGE("OpenGL: could not generate index buffer %ld\n", i);
return;
}
index_buffers_count_[i] = i==4?(int)verticesLowRes.size():(int)verticesLowLowRes.size();
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, index_buffers_[i]);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(uint32_t) * index_buffers_count_[i], i==4?verticesLowRes.data():verticesLowLowRes.data(), GL_STATIC_DRAW);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
nPoints_ = totalPoints; GLint error = glGetError();
if(error != GL_NO_ERROR)
{
LOGE("OpenGL: Could not allocate indexes (0x%x)\n", error);
index_buffers_[i] = 0;
return;
}
}
}
nPoints_ = (int)totalPoints;
} }
void PointCloudDrawable::updateMesh(const Mesh & mesh, bool createWireframe) void PointCloudDrawable::updateMesh(const rtabmap::Mesh & mesh, bool createWireframe)
{ {
UASSERT(mesh.cloud.get() && !mesh.cloud->empty()); UASSERT(mesh.cloud.get() && !mesh.cloud->empty());
nPoints_ = 0; nPoints_ = 0;
aabbMinModel_ = aabbMinWorld_ = pcl::PointXYZ(1000,1000,1000); aabbMinModel_ = aabbMinWorld_ = pcl::PointXYZ(1000,1000,1000);
aabbMaxModel_ = aabbMaxWorld_ = pcl::PointXYZ(-1000,-1000,-1000); aabbMaxModel_ = aabbMaxWorld_ = pcl::PointXYZ(-1000,-1000,-1000);
if (vertex_buffers_) if (vertex_buffer_)
{ {
glDeleteBuffers(1, &vertex_buffers_); glDeleteBuffers(1, &vertex_buffer_);
tango_gl::util::CheckGlError("PointCloudDrawable::~PointCloudDrawable()"); tango_gl::util::CheckGlError("PointCloudDrawable::updateMesh() clear vertex buffer");
vertex_buffers_ = 0; vertex_buffer_ = 0;
} }
for(size_t i=0; i<index_buffers_.size(); ++i)
{
if(index_buffers_[i])
{
glDeleteBuffers(1, &index_buffers_[i]);
index_buffers_[i] = 0;
tango_gl::util::CheckGlError("PointCloudDrawable::updateMesh() clear index buffer");
}
}
gainR_ = mesh.gains[0]; gainR_ = mesh.gains[0];
gainG_ = mesh.gains[1]; gainG_ = mesh.gains[1];
@@ -546,17 +649,17 @@ void PointCloudDrawable::updateMesh(const Mesh & mesh, bool createWireframe)
bool textureUpdate = false; bool textureUpdate = false;
if(!mesh.texture.empty() && mesh.texture.type() == CV_8UC3) if(!mesh.texture.empty() && mesh.texture.type() == CV_8UC3)
{ {
if (textures_) if (texture_)
{ {
glDeleteTextures(1, &textures_); glDeleteTextures(1, &texture_);
tango_gl::util::CheckGlError("PointCloudDrawable::~PointCloudDrawable()"); tango_gl::util::CheckGlError("PointCloudDrawable::updateMesh() clear texture buffer");
textures_ = 0; texture_ = 0;
} }
textureUpdate = true; textureUpdate = true;
} }
glGenBuffers(1, &vertex_buffers_); glGenBuffers(1, &vertex_buffer_);
if(!vertex_buffers_) if(!vertex_buffer_)
{ {
LOGE("OpenGL: could not generate vertex buffers\n"); LOGE("OpenGL: could not generate vertex buffers\n");
return; return;
@@ -564,10 +667,10 @@ void PointCloudDrawable::updateMesh(const Mesh & mesh, bool createWireframe)
if(textureUpdate) if(textureUpdate)
{ {
glGenTextures(1, &textures_); glGenTextures(1, &texture_);
if(!textures_) if(!texture_)
{ {
vertex_buffers_ = 0; vertex_buffer_ = 0;
LOGE("OpenGL: could not generate texture buffers\n"); LOGE("OpenGL: could not generate texture buffers\n");
return; return;
} }
@@ -578,18 +681,20 @@ void PointCloudDrawable::updateMesh(const Mesh & mesh, bool createWireframe)
int totalPoints = 0; int totalPoints = 0;
std::vector<pcl::Vertices> polygons = mesh.polygons; std::vector<pcl::Vertices> polygons = mesh.polygons;
std::vector<pcl::Vertices> polygonsLowRes; std::vector<pcl::Vertices> polygonsLowRes;
hasNormals_ = mesh.normals.get() && mesh.normals->size() == mesh.cloud->size(); hasNormals_ = mesh.normals.get() && mesh.normals->size() == mesh.cloud->size();
UASSERT(!hasNormals_ || mesh.cloud->size() == mesh.normals->size()); UASSERT(!hasNormals_ || mesh.cloud->size() == mesh.normals->size());
if(mesh.cloud->isOrganized()) // assume organized mesh if(mesh.cloud->isOrganized()) // assume organized mesh
{ {
polygonsLowRes = mesh.polygonsLowRes; // only in organized we keep the low res polygonsLowRes = mesh.polygonsLowRes; // only in organized we keep the low res
organizedToDenseIndices_ = std::vector<unsigned int>(mesh.cloud->width*mesh.cloud->height, -1); organizedToDenseIndices_ = std::vector<unsigned int>(mesh.cloud->width*mesh.cloud->height, -1);
totalPoints = mesh.indices->size(); totalPoints = (int)mesh.indices->size();
verticesLowRes_.resize(totalPoints); std::vector<GLuint> verticesLowRes;
verticesLowLowRes_.resize(totalPoints); std::vector<GLuint> verticesLowLowRes;
verticesLowRes.resize(totalPoints);
verticesLowLowRes.resize(totalPoints);
int oi_low = 0; int oi_low = 0;
int oi_lowlow = 0; int oi_lowlow = 0;
if(textures_ && polygons.size()) if(texture_ && polygons.size())
{ {
int items = hasNormals_?9:6; int items = hasNormals_?9:6;
vertices = std::vector<float>(mesh.indices->size()*items); vertices = std::vector<float>(mesh.indices->size()*items);
@@ -622,11 +727,11 @@ void PointCloudDrawable::updateMesh(const Mesh & mesh, bool createWireframe)
if(mesh.indices->at(i)%LOW_DEC == 0 && (mesh.indices->at(i)/mesh.cloud->width) % LOW_DEC == 0) if(mesh.indices->at(i)%LOW_DEC == 0 && (mesh.indices->at(i)/mesh.cloud->width) % LOW_DEC == 0)
{ {
verticesLowRes_[oi_low++] = i; verticesLowRes[oi_low++] = i;
} }
if(mesh.indices->at(i)%LOWLOW_DEC == 0 && (mesh.indices->at(i)/mesh.cloud->width) % LOWLOW_DEC == 0) if(mesh.indices->at(i)%LOWLOW_DEC == 0 && (mesh.indices->at(i)/mesh.cloud->width) % LOWLOW_DEC == 0)
{ {
verticesLowLowRes_[oi_lowlow++] = i; verticesLowLowRes[oi_lowlow++] = i;
} }
} }
} }
@@ -657,20 +762,48 @@ void PointCloudDrawable::updateMesh(const Mesh & mesh, bool createWireframe)
if(mesh.indices->at(i)%LOW_DEC == 0 && (mesh.indices->at(i)/mesh.cloud->width) % LOW_DEC == 0) if(mesh.indices->at(i)%LOW_DEC == 0 && (mesh.indices->at(i)/mesh.cloud->width) % LOW_DEC == 0)
{ {
verticesLowRes_[oi_low++] = i; verticesLowRes[oi_low++] = i;
} }
if(mesh.indices->at(i)%LOWLOW_DEC == 0 && (mesh.indices->at(i)/mesh.cloud->width) % LOWLOW_DEC == 0) if(mesh.indices->at(i)%LOWLOW_DEC == 0 && (mesh.indices->at(i)/mesh.cloud->width) % LOWLOW_DEC == 0)
{ {
verticesLowLowRes_[oi_lowlow++] = i; verticesLowLowRes[oi_lowlow++] = i;
} }
} }
} }
verticesLowRes_.resize(oi_low); verticesLowRes.resize(oi_low);
verticesLowLowRes_.resize(oi_lowlow); verticesLowLowRes.resize(oi_lowlow);
// vertex index buffers
for(size_t i=4; i<5; ++i)
{
if((i==4 && !verticesLowRes.empty()) ||
(i==5 && !verticesLowLowRes.empty()))
{
glGenBuffers(1, &index_buffers_[i]);
if(!index_buffers_[i])
{
LOGE("OpenGL: could not generate index buffer %ld\n", i);
return;
}
index_buffers_count_[i] = i==4?(int)verticesLowRes.size():(int)verticesLowLowRes.size();
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, index_buffers_[i]);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(uint32_t) * index_buffers_count_[i], i==4?verticesLowRes.data():verticesLowLowRes.data(), GL_STATIC_DRAW);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
GLint error = glGetError();
if(error != GL_NO_ERROR)
{
LOGE("OpenGL: Could not allocate indexes (0x%x)\n", error);
index_buffers_[i] = 0;
return;
}
}
}
} }
else // assume dense mesh with texCoords set to polygons else // assume dense mesh with texCoords set to polygons
{ {
if(textures_ && polygons.size() && mesh.normals->size()) if(texture_ && polygons.size())
{ {
//LOGD("Dense mesh with texture (%d texCoords %d points %d polygons %dx%d)", //LOGD("Dense mesh with texture (%d texCoords %d points %d polygons %dx%d)",
// (int)mesh.texCoords.size(), (int)mesh.cloud->size(), (int)mesh.polygons.size(), texture.cols, texture.rows); // (int)mesh.texCoords.size(), (int)mesh.cloud->size(), (int)mesh.polygons.size(), texture.cols, texture.rows);
@@ -679,14 +812,14 @@ void PointCloudDrawable::updateMesh(const Mesh & mesh, bool createWireframe)
// tex_coordinates should be linked to points, not // tex_coordinates should be linked to points, not
// polygon vertices. Points linked to multiple different texCoords (different textures) should // polygon vertices. Points linked to multiple different texCoords (different textures) should
// be duplicated. // be duplicated.
totalPoints = mesh.texCoords.size(); totalPoints = (int)mesh.texCoords.size();
vertices = std::vector<float>(mesh.texCoords.size()*9); int items = hasNormals_?9:6;
vertices = std::vector<float>(mesh.texCoords.size()*items);
organizedToDenseIndices_ = std::vector<unsigned int>(totalPoints, -1); organizedToDenseIndices_ = std::vector<unsigned int>(totalPoints, -1);
UASSERT_MSG(mesh.texCoords.size() == polygons[0].vertices.size()*polygons.size(), UASSERT_MSG(mesh.texCoords.size() == polygons[0].vertices.size()*polygons.size(),
uFormat("%d vs %d x %d", (int)mesh.texCoords.size(), (int)polygons[0].vertices.size(), (int)polygons.size()).c_str()); uFormat("%d vs %d x %d", (int)mesh.texCoords.size(), (int)polygons[0].vertices.size(), (int)polygons.size()).c_str());
int items = hasNormals_?9:6;
unsigned int oi=0; unsigned int oi=0;
for(unsigned int i=0; i<polygons.size(); ++i) for(unsigned int i=0; i<polygons.size(); ++i)
{ {
@@ -737,7 +870,7 @@ void PointCloudDrawable::updateMesh(const Mesh & mesh, bool createWireframe)
} }
else else
{ {
totalPoints = mesh.cloud->size(); totalPoints = (int)mesh.cloud->size();
//LOGD("Dense mesh"); //LOGD("Dense mesh");
int items = hasNormals_?7:4; int items = hasNormals_?7:4;
organizedToDenseIndices_ = std::vector<unsigned int>(totalPoints, -1); organizedToDenseIndices_ = std::vector<unsigned int>(totalPoints, -1);
@@ -765,7 +898,7 @@ void PointCloudDrawable::updateMesh(const Mesh & mesh, bool createWireframe)
} }
} }
glBindBuffer(GL_ARRAY_BUFFER, vertex_buffers_); glBindBuffer(GL_ARRAY_BUFFER, vertex_buffer_);
glBufferData(GL_ARRAY_BUFFER, sizeof(GLfloat) * (int)vertices.size(), (const void *)vertices.data(), GL_STATIC_DRAW); glBufferData(GL_ARRAY_BUFFER, sizeof(GLfloat) * (int)vertices.size(), (const void *)vertices.data(), GL_STATIC_DRAW);
glBindBuffer(GL_ARRAY_BUFFER, 0); glBindBuffer(GL_ARRAY_BUFFER, 0);
@@ -773,11 +906,11 @@ void PointCloudDrawable::updateMesh(const Mesh & mesh, bool createWireframe)
if(error != GL_NO_ERROR) if(error != GL_NO_ERROR)
{ {
LOGE("OpenGL: Could not allocate point cloud (0x%x)\n", error); LOGE("OpenGL: Could not allocate point cloud (0x%x)\n", error);
vertex_buffers_ = 0; vertex_buffer_ = 0;
return; return;
} }
if(textures_ && textureUpdate) if(texture_ && textureUpdate)
{ {
//GLint maxTextureSize = 0; //GLint maxTextureSize = 0;
//glGetIntegerv(GL_MAX_TEXTURE_SIZE, &maxTextureSize); //glGetIntegerv(GL_MAX_TEXTURE_SIZE, &maxTextureSize);
@@ -787,13 +920,13 @@ void PointCloudDrawable::updateMesh(const Mesh & mesh, bool createWireframe)
//LOGW("maxTextureUnits=%d", maxTextureUnits); //LOGW("maxTextureUnits=%d", maxTextureUnits);
// gen texture from image // gen texture from image
glBindTexture(GL_TEXTURE_2D, textures_); glBindTexture(GL_TEXTURE_2D, texture_);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
cv::Mat rgbImage; cv::Mat rgbImage;
cv::cvtColor(mesh.texture, rgbImage, CV_BGR2RGBA); cv::cvtColor(mesh.texture, rgbImage, cv::COLOR_BGR2RGBA);
glPixelStorei(GL_UNPACK_ALIGNMENT, 4); glPixelStorei(GL_UNPACK_ALIGNMENT, 4);
//glPixelStorei(GL_UNPACK_ROW_LENGTH, 0); //glPixelStorei(GL_UNPACK_ROW_LENGTH, 0);
@@ -805,20 +938,17 @@ void PointCloudDrawable::updateMesh(const Mesh & mesh, bool createWireframe)
if(error != GL_NO_ERROR) if(error != GL_NO_ERROR)
{ {
LOGE("OpenGL: Could not allocate texture (0x%x)\n", error); LOGE("OpenGL: Could not allocate texture (0x%x)\n", error);
textures_ = 0; texture_ = 0;
glDeleteBuffers(1, &vertex_buffers_); glDeleteBuffers(1, &vertex_buffer_);
vertex_buffers_ = 0; vertex_buffer_ = 0;
return; return;
} }
} }
nPoints_ = totalPoints; nPoints_ = totalPoints;
if(polygons_.size() != polygons.size()) updatePolygons(polygons, polygonsLowRes, createWireframe);
{
updatePolygons(polygons, polygonsLowRes, createWireframe);
}
if(!pose_.isNull()) if(!pose_.isNull())
{ {
@@ -880,14 +1010,14 @@ void PointCloudDrawable::Render(
bool packDepthToColorChannel, bool packDepthToColorChannel,
bool wireFrame) const bool wireFrame) const
{ {
if(vertex_buffers_ && nPoints_ && visible_ && !shaderPrograms_.empty()) if(vertex_buffer_ && nPoints_ && visible_ && !shaderPrograms_.empty())
{ {
if(packDepthToColorChannel || !hasNormals_) if(packDepthToColorChannel || !hasNormals_)
{ {
lighting = false; lighting = false;
} }
if(packDepthToColorChannel || !(meshRendering && textureRendering && textures_)) if(packDepthToColorChannel || !(meshRendering && textureRendering && texture_))
{ {
textureRendering = false; textureRendering = false;
} }
@@ -990,7 +1120,7 @@ void PointCloudDrawable::Render(
// Texture activate unit 0 // Texture activate unit 0
glActiveTexture(GL_TEXTURE0); glActiveTexture(GL_TEXTURE0);
// Bind the texture to this unit. // Bind the texture to this unit.
glBindTexture(GL_TEXTURE_2D, textures_); glBindTexture(GL_TEXTURE_2D, texture_);
// Tell the texture uniform sampler to use this texture in the shader by binding to texture unit 0. // Tell the texture uniform sampler to use this texture in the shader by binding to texture unit 0.
GLuint texture_handle = glGetUniformLocation(program, "uTexture"); GLuint texture_handle = glGetUniformLocation(program, "uTexture");
glUniform1i(texture_handle, 0); glUniform1i(texture_handle, 0);
@@ -1006,8 +1136,8 @@ void PointCloudDrawable::Render(
} }
tango_gl::util::CheckGlError("Pointcloud::Render() common"); tango_gl::util::CheckGlError("Pointcloud::Render() common");
glBindBuffer(GL_ARRAY_BUFFER, vertex_buffers_); glBindBuffer(GL_ARRAY_BUFFER, vertex_buffer_);
if(textures_) if(texture_)
{ {
glVertexAttribPointer(attribute_vertex, 3, GL_FLOAT, GL_FALSE, (hasNormals_?9:6)*sizeof(GLfloat), 0); glVertexAttribPointer(attribute_vertex, 3, GL_FLOAT, GL_FALSE, (hasNormals_?9:6)*sizeof(GLfloat), 0);
if(textureRendering) if(textureRendering)
@@ -1038,53 +1168,49 @@ void PointCloudDrawable::Render(
tango_gl::util::CheckGlError("Pointcloud::Render() set attribute pointer"); tango_gl::util::CheckGlError("Pointcloud::Render() set attribute pointer");
UTimer drawTime; UTimer drawTime;
if(textureRendering) if((textureRendering || meshRendering) && index_buffers_[0])
{ {
if(distanceToCameraSqr<16.0f || polygonsLowRes_.empty()) float dist = meshRendering?50.0f:16.0f;
if(distanceToCameraSqr<dist || index_buffers_[1]==0)
{ {
wireFrame = wireFrame && polygonLines_.size(); wireFrame = wireFrame && index_buffers_[2];
if(wireFrame) if(wireFrame)
glDrawElements(GL_LINES, polygonLines_.size(), GL_UNSIGNED_INT, polygonLines_.data()); {
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, index_buffers_[2]);
glDrawElements(GL_LINES, index_buffers_count_[2], GL_UNSIGNED_INT, 0);
}
else else
glDrawElements(GL_TRIANGLES, polygons_.size(), GL_UNSIGNED_INT, polygons_.data()); {
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, index_buffers_[0]);
glDrawElements(GL_TRIANGLES, index_buffers_count_[0], GL_UNSIGNED_INT, 0);
}
} }
else else
{ {
wireFrame = wireFrame && polygonLinesLowRes_.size(); wireFrame = wireFrame && index_buffers_[3];
if(wireFrame) if(wireFrame)
glDrawElements(GL_LINES, polygonLinesLowRes_.size(), GL_UNSIGNED_INT, polygonLinesLowRes_.data()); {
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, index_buffers_[3]);
glDrawElements(GL_LINES, index_buffers_count_[3], GL_UNSIGNED_INT, 0);
}
else else
glDrawElements(GL_TRIANGLES, polygonsLowRes_.size(), GL_UNSIGNED_INT, polygonsLowRes_.data()); {
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, index_buffers_[1]);
glDrawElements(GL_TRIANGLES, index_buffers_count_[1], GL_UNSIGNED_INT, 0);
}
} }
} }
else if(meshRendering && polygons_.size()) else if(index_buffers_[4])
{ {
if(distanceToCameraSqr<50.0f || polygonsLowRes_.empty()) if(distanceToCameraSqr>600.0f && index_buffers_[5])
{ {
wireFrame = wireFrame && polygonLines_.size(); glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, index_buffers_[5]);
if(wireFrame) glDrawElements(GL_POINTS, index_buffers_count_[5], GL_UNSIGNED_INT, 0);
glDrawElements(GL_LINES, polygonLines_.size(), GL_UNSIGNED_INT, polygonLines_.data());
else
glDrawElements(GL_TRIANGLES, polygons_.size(), GL_UNSIGNED_INT, polygons_.data());
}
else
{
wireFrame = wireFrame && polygonLinesLowRes_.size();
if(wireFrame)
glDrawElements(GL_LINES, polygonLinesLowRes_.size(), GL_UNSIGNED_INT, polygonLinesLowRes_.data());
else
glDrawElements(GL_TRIANGLES, polygonsLowRes_.size(), GL_UNSIGNED_INT, polygonsLowRes_.data());
}
}
else if(!verticesLowRes_.empty())
{
if(distanceToCameraSqr>600.0f)
{
glDrawElements(GL_POINTS, verticesLowLowRes_.size(), GL_UNSIGNED_INT, verticesLowLowRes_.data());
} }
else if(distanceToCameraSqr>150.0f) else if(distanceToCameraSqr>150.0f)
{ {
glDrawElements(GL_POINTS, verticesLowRes_.size(), GL_UNSIGNED_INT, verticesLowRes_.data()); glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, index_buffers_[4]);
glDrawElements(GL_POINTS, index_buffers_count_[4], GL_UNSIGNED_INT, 0);
} }
else else
{ {
@@ -1100,6 +1226,7 @@ void PointCloudDrawable::Render(
glDisableVertexAttribArray(0); glDisableVertexAttribArray(0);
glBindBuffer(GL_ARRAY_BUFFER, 0); glBindBuffer(GL_ARRAY_BUFFER, 0);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
glUseProgram(0); glUseProgram(0);
tango_gl::util::CheckGlError("Pointcloud::Render() cleaning"); tango_gl::util::CheckGlError("Pointcloud::Render() cleaning");
+10 -12
View File
@@ -28,7 +28,9 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#ifndef TANGO_POINT_CLOUD_POINT_CLOUD_DRAWABLE_H_ #ifndef TANGO_POINT_CLOUD_POINT_CLOUD_DRAWABLE_H_
#define TANGO_POINT_CLOUD_POINT_CLOUD_DRAWABLE_H_ #define TANGO_POINT_CLOUD_POINT_CLOUD_DRAWABLE_H_
#ifdef __ANDROID__
#include <jni.h> #include <jni.h>
#endif
#include <tango-gl/util.h> #include <tango-gl/util.h>
#include <vector> #include <vector>
@@ -55,21 +57,21 @@ private:
float gainG = 1.0f, float gainG = 1.0f,
float gainB = 1.0f); float gainB = 1.0f);
PointCloudDrawable( PointCloudDrawable(
const Mesh & mesh, const rtabmap::Mesh & mesh,
bool createWireframe = false); bool createWireframe = false);
virtual ~PointCloudDrawable(); virtual ~PointCloudDrawable();
void updatePolygons(const std::vector<pcl::Vertices> & polygons, const std::vector<pcl::Vertices> & polygonsLowRes = std::vector<pcl::Vertices>(), bool createWireframe = false); void updatePolygons(const std::vector<pcl::Vertices> & polygons, const std::vector<pcl::Vertices> & polygonsLowRes = std::vector<pcl::Vertices>(), bool createWireframe = false);
void updateCloud(const pcl::PointCloud<pcl::PointXYZRGB>::Ptr & cloud, const pcl::IndicesPtr & indices); void updateCloud(const pcl::PointCloud<pcl::PointXYZRGB>::Ptr & cloud, const pcl::IndicesPtr & indices);
void updateMesh(const Mesh & mesh, bool createWireframe = false); void updateMesh(const rtabmap::Mesh & mesh, bool createWireframe = false);
void setPose(const rtabmap::Transform & pose); void setPose(const rtabmap::Transform & pose);
void setVisible(bool visible) {visible_=visible;} void setVisible(bool visible) {visible_=visible;}
void setGains(float gainR, float gainG, float gainB) {gainR_ = gainR; gainG_ = gainG; gainB_ = gainB;} void setGains(float gainR, float gainG, float gainB) {gainR_ = gainR; gainG_ = gainG; gainB_ = gainB;}
rtabmap::Transform getPose() const {return pose_;} rtabmap::Transform getPose() const {return pose_;}
const glm::mat4 & getPoseGl() const {return poseGl_;} const glm::mat4 & getPoseGl() const {return poseGl_;}
bool isVisible() const {return visible_;} bool isVisible() const {return visible_;}
bool hasMesh() const {return polygons_.size()!=0;} bool hasMesh() const {return index_buffers_[0] != 0;}
bool hasTexture() const {return textures_ != 0;} bool hasTexture() const {return texture_ != 0;}
float getMinHeight() const {return minHeight_;} float getMinHeight() const {return minHeight_;}
const pcl::PointXYZ & aabbMinModel() const {return aabbMinModel_;} const pcl::PointXYZ & aabbMinModel() const {return aabbMinModel_;}
const pcl::PointXYZ & aabbMaxModel() const {return aabbMaxModel_;} const pcl::PointXYZ & aabbMaxModel() const {return aabbMaxModel_;}
@@ -113,14 +115,10 @@ private:
private: private:
// Vertex buffer of the point cloud geometry. // Vertex buffer of the point cloud geometry.
GLuint vertex_buffers_; GLuint vertex_buffer_;
GLuint textures_; GLuint texture_;
std::vector<GLuint> polygons_; std::vector<GLuint> index_buffers_;
std::vector<GLuint> polygonsLowRes_; std::vector<int> index_buffers_count_;
std::vector<GLuint> polygonLines_;
std::vector<GLuint> polygonLinesLowRes_;
std::vector<GLuint> verticesLowRes_;
std::vector<GLuint> verticesLowLowRes_;
int nPoints_; int nPoints_;
rtabmap::Transform pose_; rtabmap::Transform pose_;
glm::mat4 poseGl_; glm::mat4 poseGl_;
+212 -67
View File
@@ -69,6 +69,7 @@ const std::string kGraphFragmentShader =
Scene::Scene() : Scene::Scene() :
background_renderer_(0),
gesture_camera_(0), gesture_camera_(0),
axis_(0), axis_(0),
frustum_(0), frustum_(0),
@@ -79,14 +80,15 @@ Scene::Scene() :
graphVisible_(true), graphVisible_(true),
gridVisible_(true), gridVisible_(true),
traceVisible_(true), traceVisible_(true),
color_camera_to_display_rotation_(ROTATION_0), frustumVisible_(true),
color_camera_to_display_rotation_(rtabmap::ROTATION_0),
currentPose_(0), currentPose_(0),
graph_shader_program_(0), graph_shader_program_(0),
blending_(true), blending_(true),
mapRendering_(true), mapRendering_(true),
meshRendering_(true), meshRendering_(true),
meshRenderingTexture_(true), meshRenderingTexture_(true),
pointSize_(5.0f), pointSize_(10.0f),
boundingBoxRendering_(false), boundingBoxRendering_(false),
lighting_(false), lighting_(false),
backfaceCulling_(true), backfaceCulling_(true),
@@ -95,19 +97,21 @@ Scene::Scene() :
g_(0.0f), g_(0.0f),
b_(0.0f), b_(0.0f),
fboId_(0), fboId_(0),
depthTexture_(0), rboId_(0),
screenWidth_(0), screenWidth_(0),
screenHeight_(0), screenHeight_(0),
doubleTapOn_(false) doubleTapOn_(false)
{ {
depthTexture_ = 0;
gesture_camera_ = new tango_gl::GestureCamera(); gesture_camera_ = new tango_gl::GestureCamera();
gesture_camera_->SetCameraType( gesture_camera_->SetCameraType(
tango_gl::GestureCamera::kFirstPerson); tango_gl::GestureCamera::kThirdPersonFollow);
} }
Scene::~Scene() { Scene::~Scene() {
DeleteResources(); DeleteResources();
delete gesture_camera_; delete gesture_camera_;
delete currentPose_;
} }
//Should only be called in OpenGL thread! //Should only be called in OpenGL thread!
@@ -126,7 +130,6 @@ void Scene::InitGLContent()
trace_ = new tango_gl::Trace(); trace_ = new tango_gl::Trace();
grid_ = new tango_gl::Grid(); grid_ = new tango_gl::Grid();
box_ = new BoundingBoxDrawable(); box_ = new BoundingBoxDrawable();
currentPose_ = new rtabmap::Transform();
axis_->SetScale(glm::vec3(0.5f,0.5f,0.5f)); axis_->SetScale(glm::vec3(0.5f,0.5f,0.5f));
@@ -158,8 +161,9 @@ void Scene::DeleteResources() {
delete frustum_; delete frustum_;
delete trace_; delete trace_;
delete grid_; delete grid_;
delete currentPose_;
delete box_; delete box_;
delete background_renderer_;
background_renderer_ = 0;
} }
PointCloudDrawable::releaseShaderPrograms(); PointCloudDrawable::releaseShaderPrograms();
@@ -173,8 +177,10 @@ void Scene::DeleteResources() {
{ {
glDeleteFramebuffers(1, &fboId_); glDeleteFramebuffers(1, &fboId_);
fboId_ = 0; fboId_ = 0;
glDeleteTextures(1, &depthTexture_); glDeleteRenderbuffers(1, &rboId_);
depthTexture_ = 0; rboId_ = 0;
glDeleteTextures(1, &depthTexture_);
depthTexture_ = 0;
} }
clear(); clear();
@@ -188,6 +194,10 @@ void Scene::clear()
{ {
delete iter->second; delete iter->second;
} }
for(std::map<int, tango_gl::Axis*>::iterator iter=markers_.begin(); iter!=markers_.end(); ++iter)
{
delete iter->second;
}
if(trace_) if(trace_)
{ {
trace_->ClearVertexArray(); trace_->ClearVertexArray();
@@ -198,6 +208,7 @@ void Scene::clear()
graph_ = 0; graph_ = 0;
} }
pointClouds_.clear(); pointClouds_.clear();
markers_.clear();
if(grid_) if(grid_)
{ {
grid_->SetPosition(kHeightOffset); grid_->SetPosition(kHeightOffset);
@@ -209,19 +220,32 @@ void Scene::SetupViewPort(int w, int h) {
if (h == 0) { if (h == 0) {
LOGE("Setup graphic height not valid"); LOGE("Setup graphic height not valid");
} }
UASSERT(gesture_camera_ != 0); UASSERT(gesture_camera_ != 0);
gesture_camera_->SetWindowSize(static_cast<float>(w), static_cast<float>(h)); gesture_camera_->SetWindowSize(static_cast<float>(w), static_cast<float>(h));
glViewport(0, 0, w, h); glViewport(0, 0, w, h);
if(screenWidth_ != w || fboId_ == 0) if(screenWidth_ != w || screenHeight_ != h || fboId_ == 0)
{ {
UINFO("Setup viewport OpenGL: %dx%d", w, h);
if(fboId_>0) if(fboId_>0)
{ {
glDeleteFramebuffers(1, &fboId_); glDeleteFramebuffers(1, &fboId_);
fboId_ = 0; fboId_ = 0;
glDeleteRenderbuffers(1, &rboId_);
rboId_ = 0;
glDeleteTextures(1, &depthTexture_); glDeleteTextures(1, &depthTexture_);
depthTexture_ = 0; depthTexture_ = 0;
} }
GLint originid = 0;
glGetIntegerv(GL_FRAMEBUFFER_BINDING, &originid);
// regenerate fbo texture
// create a framebuffer object, you need to delete them when program exits.
glGenFramebuffers(1, &fboId_);
glBindFramebuffer(GL_FRAMEBUFFER, fboId_);
// Create depth texture // Create depth texture
glGenTextures(1, &depthTexture_); glGenTextures(1, &depthTexture_);
glBindTexture(GL_TEXTURE_2D, depthTexture_); glBindTexture(GL_TEXTURE_2D, depthTexture_);
@@ -229,24 +253,22 @@ void Scene::SetupViewPort(int w, int h) {
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT, w, h, 0, GL_DEPTH_COMPONENT, GL_UNSIGNED_INT, NULL); glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, w, h, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL);
glBindTexture(GL_TEXTURE_2D, 0); glBindTexture(GL_TEXTURE_2D, 0);
glGenRenderbuffers(1, &rboId_);
glBindRenderbuffer(GL_RENDERBUFFER, rboId_);
glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT16, w, h);
glBindRenderbuffer(GL_RENDERBUFFER, 0);
// regenerate fbo texture // Set the texture to be at the color attachment point of the FBO (we pack depth 32 bits in color)
// create a framebuffer object, you need to delete them when program exits. glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, depthTexture_, 0);
glGenFramebuffers(1, &fboId_); glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, rboId_);
glBindFramebuffer(GL_FRAMEBUFFER, fboId_);
// Set the texture to be at the depth attachment point of the FBO
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D, depthTexture_, 0);
GLuint status = glCheckFramebufferStatus(GL_FRAMEBUFFER); GLuint status = glCheckFramebufferStatus(GL_FRAMEBUFFER);
if ( status != GL_FRAMEBUFFER_COMPLETE) UASSERT ( status == GL_FRAMEBUFFER_COMPLETE);
{ glBindFramebuffer(GL_FRAMEBUFFER, originid);
LOGE("Frame buffer cannot be generated! Status: %in", status); }
}
glBindFramebuffer(GL_FRAMEBUFFER,0);
}
screenWidth_ = w; screenWidth_ = w;
screenHeight_ = h; screenHeight_ = h;
} }
@@ -319,8 +341,9 @@ std::vector<glm::vec4> computeFrustumPlanes(const glm::mat4 & mat, bool normaliz
/** /**
* Tells whether or not b is intersecting f. * Tells whether or not b is intersecting f.
* http://www.txutxi.com/?p=584 * http://www.txutxi.com/?p=584
* @param f Viewing frustum. * @param planes Viewing frustum.
* @param b An axis aligned bounding box. * @param boxMin The axis aligned bounding box min.
* @param boxMax The axis aligned bounding box max.
* @return True if b intersects f, false otherwise. * @return True if b intersects f, false otherwise.
*/ */
bool intersectFrustumAABB( bool intersectFrustumAABB(
@@ -359,9 +382,14 @@ bool intersectFrustumAABB(
} }
//Should only be called in OpenGL thread! //Should only be called in OpenGL thread!
int Scene::Render() { int Scene::Render(const float * uvsTransformed, glm::mat4 arViewMatrix, glm::mat4 arProjectionMatrix, const rtabmap::Mesh & occlusionMesh, bool mapping)
{
UASSERT(gesture_camera_ != 0); UASSERT(gesture_camera_ != 0);
if(currentPose_ == 0)
{
currentPose_ = new rtabmap::Transform(0,0,0,0,0,-M_PI/2.0f);
}
glm::vec3 position(currentPose_->x(), currentPose_->y(), currentPose_->z()); glm::vec3 position(currentPose_->x(), currentPose_->y(), currentPose_->z());
Eigen::Quaternionf quat = currentPose_->getQuaternionf(); Eigen::Quaternionf quat = currentPose_->getQuaternionf();
glm::quat rotation(quat.w(), quat.x(), quat.y(), quat.z()); glm::quat rotation(quat.w(), quat.x(), quat.y(), quat.z());
@@ -386,6 +414,25 @@ int Scene::Render() {
glm::mat4 projectionMatrix = gesture_camera_->GetProjectionMatrix(); glm::mat4 projectionMatrix = gesture_camera_->GetProjectionMatrix();
glm::mat4 viewMatrix = gesture_camera_->GetViewMatrix(); glm::mat4 viewMatrix = gesture_camera_->GetViewMatrix();
bool renderBackgroundCamera =
background_renderer_ &&
gesture_camera_->GetCameraType() == tango_gl::GestureCamera::kFirstPerson &&
!rtabmap::glmToTransform(arProjectionMatrix).isNull() &&
uvsTransformed;
if(renderBackgroundCamera)
{
if(projectionMatrix[0][0] > arProjectionMatrix[0][0]-0.3)
{
projectionMatrix = arProjectionMatrix;
viewMatrix = arViewMatrix;
}
else
{
renderBackgroundCamera = false;
}
}
rtabmap::Transform openglCamera = GetOpenGLCameraPose();//*rtabmap::Transform(0.0f, 0.0f, 3.0f, 0.0f, 0.0f, 0.0f); rtabmap::Transform openglCamera = GetOpenGLCameraPose();//*rtabmap::Transform(0.0f, 0.0f, 3.0f, 0.0f, 0.0f, 0.0f);
// transform in same coordinate as frustum filtering // transform in same coordinate as frustum filtering
openglCamera *= rtabmap::Transform( openglCamera *= rtabmap::Transform(
@@ -433,28 +480,45 @@ int Scene::Render() {
glDisable(GL_CULL_FACE); glDisable(GL_CULL_FACE);
} }
UTimer timer; bool onlineBlending =
(!meshRendering_ &&
occlusionMesh.cloud.get() &&
occlusionMesh.cloud->size()) ||
(blending_ &&
gesture_camera_->GetCameraType()!=tango_gl::GestureCamera::kTopOrtho &&
mapRendering_ && meshRendering_ &&
(cloudsToDraw.size() > 1 || (renderBackgroundCamera && wireFrame_)));
bool onlineBlending = blending_ && gesture_camera_->GetCameraType()!=tango_gl::GestureCamera::kTopOrtho && mapRendering_ && meshRendering_ && cloudsToDraw.size()>1;
if(onlineBlending && fboId_) if(onlineBlending && fboId_)
{ {
GLint originid = 0;
glGetIntegerv(GL_FRAMEBUFFER_BINDING, &originid);
// set the rendering destination to FBO // set the rendering destination to FBO
glBindFramebuffer(GL_FRAMEBUFFER, fboId_); glBindFramebuffer(GL_FRAMEBUFFER, fboId_);
glColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE); glClearColor(0, 0, 0, 0);
glClearColor(1, 1, 1, 1);
glClear(GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT); glClear(GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT);
// Draw scene // Draw scene
for(std::vector<PointCloudDrawable*>::const_iterator iter=cloudsToDraw.begin(); iter!=cloudsToDraw.end(); ++iter) for(std::vector<PointCloudDrawable*>::const_iterator iter=cloudsToDraw.begin(); iter!=cloudsToDraw.end(); ++iter)
{ {
// set large distance to cam to use low res polygons for fast processing Eigen::Vector3f cloudToCamera(
(*iter)->Render(projectionMatrix, viewMatrix, meshRendering_, pointSize_, false, false, 999.0f); (*iter)->getPose().x() - openglCamera.x(),
} (*iter)->getPose().y() - openglCamera.y(),
(*iter)->getPose().z() - openglCamera.z());
float distanceToCameraSqr = cloudToCamera[0]*cloudToCamera[0] + cloudToCamera[1]*cloudToCamera[1] + cloudToCamera[2]*cloudToCamera[2];
(*iter)->Render(projectionMatrix, viewMatrix, meshRendering_, pointSize_, false, false, distanceToCameraSqr, 0, 0, 0, 0, 0, true);
}
if(!meshRendering_ && occlusionMesh.cloud.get() && occlusionMesh.cloud->size())
{
PointCloudDrawable drawable(occlusionMesh);
drawable.Render(projectionMatrix, viewMatrix, true, pointSize_, false, false, 0, 0, 0, 0, 0, 0, true);
}
// back to normal window-system-provided framebuffer // back to normal window-system-provided framebuffer
glBindFramebuffer(GL_FRAMEBUFFER, 0); // unbind glBindFramebuffer(GL_FRAMEBUFFER, originid); // unbind
glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
} }
if(doubleTapOn_ && gesture_camera_->GetCameraType() != tango_gl::GestureCamera::kFirstPerson) if(doubleTapOn_ && gesture_camera_->GetCameraType() != tango_gl::GestureCamera::kFirstPerson)
@@ -462,16 +526,21 @@ int Scene::Render() {
glClearColor(0, 0, 0, 0); glClearColor(0, 0, 0, 0);
glClear(GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT); glClear(GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT);
// FIXME: we could use the depthTexture if already computed!
for(std::vector<PointCloudDrawable*>::const_iterator iter=cloudsToDraw.begin(); iter!=cloudsToDraw.end(); ++iter) for(std::vector<PointCloudDrawable*>::const_iterator iter=cloudsToDraw.begin(); iter!=cloudsToDraw.end(); ++iter)
{ {
// set large distance to cam to use low res polygons for fast processing Eigen::Vector3f cloudToCamera(
(*iter)->Render(projectionMatrix, viewMatrix, meshRendering_, pointSize_*10.0f, false, false, 999.0f, 0, 0, 0, 0, 0, true); (*iter)->getPose().x() - openglCamera.x(),
(*iter)->getPose().y() - openglCamera.y(),
(*iter)->getPose().z() - openglCamera.z());
float distanceToCameraSqr = cloudToCamera[0]*cloudToCamera[0] + cloudToCamera[1]*cloudToCamera[1] + cloudToCamera[2]*cloudToCamera[2];
(*iter)->Render(projectionMatrix, viewMatrix, meshRendering_, pointSize_*10.0f, false, false, distanceToCameraSqr, 0, 0, 0, 0, 0, true);
} }
GLubyte zValue[4]; GLubyte zValue[4];
glReadPixels(doubleTapPos_.x*screenWidth_, screenHeight_-doubleTapPos_.y*screenHeight_, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, zValue); glReadPixels(doubleTapPos_.x*screenWidth_, screenHeight_-doubleTapPos_.y*screenHeight_, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, zValue);
float fromFixed = 256.0f/255.0f; float zValueF = float(zValue[0]/255.0f) + float(zValue[1]/255.0f)/255.0f + float(zValue[2]/255.0f)/65025.0f + float(zValue[3]/255.0f)/160581375.0f;
float zValueF = float(zValue[0]/255.0f)*fromFixed + float(zValue[1]/255.0f)*fromFixed/255.0f + float(zValue[2]/255.0f)*fromFixed/65025.0f + float(zValue[3]/255.0f)*fromFixed/160581375.0f;
if(zValueF != 0.0f) if(zValueF != 0.0f)
{ {
@@ -485,10 +554,19 @@ int Scene::Render() {
glClearColor(r_, g_, b_, 1.0f); glClearColor(r_, g_, b_, 1.0f);
glClear(GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT); glClear(GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT);
if(renderBackgroundCamera && (!onlineBlending || !meshRendering_))
{
background_renderer_->Draw(uvsTransformed, 0, screenWidth_, screenHeight_, false);
//To debug occlusion image:
//PointCloudDrawable drawable(occlusionMesh);
//drawable.Render(projectionMatrix, viewMatrix, true, pointSize_, false, false, 999.0f);
}
if(!currentPose_->isNull()) if(!currentPose_->isNull())
{ {
if (gesture_camera_->GetCameraType() != tango_gl::GestureCamera::kFirstPerson) if (frustumVisible_ && gesture_camera_->GetCameraType() != tango_gl::GestureCamera::kFirstPerson)
{ {
frustum_->SetPosition(position); frustum_->SetPosition(position);
frustum_->SetRotation(rotation); frustum_->SetRotation(rotation);
@@ -497,8 +575,13 @@ int Scene::Render() {
frustum_->SetScale(kFrustumScale); frustum_->SetScale(kFrustumScale);
frustum_->Render(projectionMatrix, viewMatrix); frustum_->Render(projectionMatrix, viewMatrix);
axis_->SetPosition(position); rtabmap::Transform cameraFrame = *currentPose_*rtabmap::optical_T_opengl*rtabmap::CameraMobile::opticalRotationInv;
axis_->SetRotation(rotation); glm::vec3 positionCamera(cameraFrame.x(), cameraFrame.y(), cameraFrame.z());
Eigen::Quaternionf quatCamera = cameraFrame.getQuaternionf();
glm::quat rotationCamera(quatCamera.w(), quatCamera.x(), quatCamera.y(), quatCamera.z());
axis_->SetPosition(positionCamera);
axis_->SetRotation(rotationCamera);
axis_->Render(projectionMatrix, viewMatrix); axis_->Render(projectionMatrix, viewMatrix);
} }
@@ -507,11 +590,15 @@ int Scene::Render() {
{ {
trace_->Render(projectionMatrix, viewMatrix); trace_->Render(projectionMatrix, viewMatrix);
} }
else
{
trace_->ClearVertexArray();
}
}
if(gridVisible_) if(gridVisible_ && !renderBackgroundCamera)
{ {
grid_->Render(projectionMatrix, viewMatrix); grid_->Render(projectionMatrix, viewMatrix);
}
} }
if(graphVisible_ && graph_) if(graphVisible_ && graph_)
@@ -547,9 +634,20 @@ int Scene::Render() {
if(onlineBlending) if(onlineBlending)
{ {
if(renderBackgroundCamera && meshRendering_)
{
background_renderer_->Draw(uvsTransformed, depthTexture_, screenWidth_, screenHeight_, mapping);
}
glDisable (GL_BLEND); glDisable (GL_BLEND);
glDepthMask(GL_TRUE); glDepthMask(GL_TRUE);
} }
//draw markers on foreground
for(std::map<int, tango_gl::Axis*>::const_iterator iter=markers_.begin(); iter!=markers_.end(); ++iter)
{
iter->second->Render(projectionMatrix, viewMatrix);
}
return (int)cloudsToDraw.size(); return (int)cloudsToDraw.size();
} }
@@ -560,8 +658,11 @@ void Scene::SetCameraType(tango_gl::GestureCamera::CameraType camera_type) {
void Scene::SetCameraPose(const rtabmap::Transform & pose) void Scene::SetCameraPose(const rtabmap::Transform & pose)
{ {
UASSERT(currentPose_ != 0);
UASSERT(!pose.isNull()); UASSERT(!pose.isNull());
if(currentPose_ ==0)
{
currentPose_ = new rtabmap::Transform(0,0,0,0,0,-M_PI/2.0f);
}
*currentPose_ = pose; *currentPose_ = pose;
} }
@@ -589,7 +690,7 @@ rtabmap::Transform Scene::GetOpenGLCameraPose(float * fov) const
{ {
*fov = gesture_camera_->getFOV(); *fov = gesture_camera_->getFOV();
} }
return glmToTransform(gesture_camera_->GetTransformationMatrix()); return rtabmap::glmToTransform(gesture_camera_->GetTransformationMatrix());
} }
void Scene::OnTouchEvent(int touch_count, void Scene::OnTouchEvent(int touch_count,
@@ -618,18 +719,10 @@ void Scene::updateGraph(
const std::multimap<int, rtabmap::Link> & links) const std::multimap<int, rtabmap::Link> & links)
{ {
LOGI("updateGraph"); LOGI("updateGraph");
if(graph_)
{
delete graph_;
graph_ = 0;
}
//create //create
if(graphVisible_) UASSERT(graph_shader_program_ != 0);
{ delete graph_;
UASSERT(graph_shader_program_ != 0); graph_ = new GraphDrawable(graph_shader_program_, poses, links);
graph_ = new GraphDrawable(graph_shader_program_, poses, links);
}
} }
void Scene::setGraphVisible(bool visible) void Scene::setGraphVisible(bool visible)
@@ -647,7 +740,59 @@ void Scene::setTraceVisible(bool visible)
traceVisible_ = visible; traceVisible_ = visible;
} }
void Scene::setFrustumVisible(bool visible)
{
frustumVisible_ = visible;
}
//Should only be called in OpenGL thread! //Should only be called in OpenGL thread!
void Scene::addMarker(
int id,
const rtabmap::Transform & pose)
{
LOGI("add marker %d", id);
std::map<int, tango_gl::Axis*>::iterator iter=markers_.find(id);
if(iter == markers_.end())
{
//create
tango_gl::Axis * drawable = new tango_gl::Axis();
drawable->SetScale(glm::vec3(0.05f,0.05f,0.05f));
drawable->SetLineWidth(5);
markers_.insert(std::make_pair(id, drawable));
}
setMarkerPose(id, pose);
}
void Scene::setMarkerPose(int id, const rtabmap::Transform & pose)
{
UASSERT(!pose.isNull());
std::map<int, tango_gl::Axis*>::iterator iter=markers_.find(id);
if(iter != markers_.end())
{
glm::vec3 position(pose.x(), pose.y(), pose.z());
Eigen::Quaternionf quat = pose.getQuaternionf();
glm::quat rotation(quat.w(), quat.x(), quat.y(), quat.z());
iter->second->SetPosition(position);
iter->second->SetRotation(rotation);
}
}
bool Scene::hasMarker(int id) const
{
return markers_.find(id) != markers_.end();
}
void Scene::removeMarker(int id)
{
std::map<int, tango_gl::Axis*>::iterator iter=markers_.find(id);
if(iter != markers_.end())
{
delete iter->second;
markers_.erase(iter);
}
}
std::set<int> Scene::getAddedMarkers() const
{
return uKeysSet(markers_);
}
void Scene::addCloud( void Scene::addCloud(
int id, int id,
const pcl::PointCloud<pcl::PointXYZRGB>::Ptr & cloud, const pcl::PointCloud<pcl::PointXYZRGB>::Ptr & cloud,
@@ -670,7 +815,7 @@ void Scene::addCloud(
void Scene::addMesh( void Scene::addMesh(
int id, int id,
const Mesh & mesh, const rtabmap::Mesh & mesh,
const rtabmap::Transform & pose, const rtabmap::Transform & pose,
bool createWireframe) bool createWireframe)
{ {
@@ -789,7 +934,7 @@ void Scene::updateCloudPolygons(int id, const std::vector<pcl::Vertices> & polyg
} }
} }
void Scene::updateMesh(int id, const Mesh & mesh) void Scene::updateMesh(int id, const rtabmap::Mesh & mesh)
{ {
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())
+30 -11
View File
@@ -17,11 +17,13 @@
#ifndef TANGO_POINT_CLOUD_SCENE_H_ #ifndef TANGO_POINT_CLOUD_SCENE_H_
#define TANGO_POINT_CLOUD_SCENE_H_ #define TANGO_POINT_CLOUD_SCENE_H_
#ifdef __ANDROID__
#include <jni.h> #include <jni.h>
#endif
#include <memory> #include <memory>
#include <set> #include <set>
#include <tango_client_api.h> // NOLINT #include "CameraMobile.h"
#include <tango-gl/axis.h> #include <tango-gl/axis.h>
#include <tango-gl/camera.h> #include <tango-gl/camera.h>
#include <tango-gl/color.h> #include <tango-gl/color.h>
@@ -35,9 +37,10 @@
#include <rtabmap/core/Transform.h> #include <rtabmap/core/Transform.h>
#include <rtabmap/core/Link.h> #include <rtabmap/core/Link.h>
#include <point_cloud_drawable.h> #include "point_cloud_drawable.h"
#include <graph_drawable.h> #include "graph_drawable.h"
#include <bounding_box_drawable.h> #include "bounding_box_drawable.h"
#include "background_renderer.h"
#include <pcl/point_cloud.h> #include <pcl/point_cloud.h>
#include <pcl/point_types.h> #include <pcl/point_types.h>
@@ -60,7 +63,8 @@ class Scene {
int getViewPortWidth() const {return screenWidth_;} int getViewPortWidth() const {return screenWidth_;}
int getViewPortHeight() const {return screenHeight_;} int getViewPortHeight() const {return screenHeight_;}
void setScreenRotation(TangoSupportRotation colorCameraToDisplayRotation) {color_camera_to_display_rotation_ = colorCameraToDisplayRotation;} rtabmap::ScreenRotation getScreenRotation() const {return color_camera_to_display_rotation_;}
void setScreenRotation(rtabmap::ScreenRotation colorCameraToDisplayRotation) {color_camera_to_display_rotation_ = colorCameraToDisplayRotation;}
void clear(); // removed all point clouds void clear(); // removed all point clouds
@@ -70,15 +74,16 @@ class Scene {
// frame's timestamp. // frame's timestamp.
// @param: point_cloud_vertices, point cloud's vertices of the current point // @param: point_cloud_vertices, point cloud's vertices of the current point
// frame. // frame.
int Render(); int Render(const float * uvsTransformed = 0, glm::mat4 arViewMatrix = glm::mat4(0), glm::mat4 arProjectionMatrix=glm::mat4(0), const rtabmap::Mesh & occlusionMesh=rtabmap::Mesh(), bool mapping=false);
// Set render camera's viewing angle, first person, third person or top down. // Set render camera's viewing angle, first person, third person or top down.
// //
// @param: camera_type, camera type includes first person, third person and // @param: camera_type, camera type includes first person, third person and
// top down // top down
void SetCameraType(tango_gl::GestureCamera::CameraType camera_type); void SetCameraType(tango_gl::GestureCamera::CameraType camera_type);
tango_gl::GestureCamera::CameraType GetCameraType() const {return gesture_camera_->GetCameraType();}
void SetCameraPose(const rtabmap::Transform & pose); void SetCameraPose(const rtabmap::Transform & pose); // opengl camera
rtabmap::Transform GetCameraPose() const {return currentPose_!=0?*currentPose_:rtabmap::Transform();} rtabmap::Transform GetCameraPose() const {return currentPose_!=0?*currentPose_:rtabmap::Transform();}
rtabmap::Transform GetOpenGLCameraPose(float * fov = 0) const; rtabmap::Transform GetOpenGLCameraPose(float * fov = 0) const;
@@ -101,6 +106,13 @@ class Scene {
void setGraphVisible(bool visible); void setGraphVisible(bool visible);
void setGridVisible(bool visible); void setGridVisible(bool visible);
void setTraceVisible(bool visible); void setTraceVisible(bool visible);
void setFrustumVisible(bool visible);
void addMarker(int id, const rtabmap::Transform & pose);
void setMarkerPose(int id, const rtabmap::Transform & pose);
bool hasMarker(int id) const;
void removeMarker(int id);
std::set<int> getAddedMarkers() const;
void addCloud( void addCloud(
int id, int id,
@@ -109,7 +121,7 @@ class Scene {
const rtabmap::Transform & pose); const rtabmap::Transform & pose);
void addMesh( void addMesh(
int id, int id,
const Mesh & mesh, const rtabmap::Mesh & mesh,
const rtabmap::Transform & pose, const rtabmap::Transform & pose,
bool createWireframe = false); bool createWireframe = false);
@@ -120,7 +132,7 @@ class Scene {
bool hasTexture(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 updateCloudPolygons(int id, const std::vector<pcl::Vertices> & polygons);
void updateMesh(int id, const Mesh & mesh); void updateMesh(int id, const rtabmap::Mesh & mesh);
void updateGains(int id, float gainR, float gainG, float gainB); void updateGains(int id, float gainR, float gainG, float gainB);
void setBlending(bool enabled) {blending_ = enabled;} void setBlending(bool enabled) {blending_ = enabled;}
@@ -143,6 +155,9 @@ class Scene {
float getPointSize() const {return pointSize_;} float getPointSize() const {return pointSize_;}
bool isLighting() const {return lighting_;} bool isLighting() const {return lighting_;}
bool isBackfaceCulling() const {return backfaceCulling_;} bool isBackfaceCulling() const {return backfaceCulling_;}
bool isWireframe() const {return wireFrame_;}
BackgroundRenderer * background_renderer_;
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.
@@ -166,8 +181,11 @@ class Scene {
bool graphVisible_; bool graphVisible_;
bool gridVisible_; bool gridVisible_;
bool traceVisible_; bool traceVisible_;
bool frustumVisible_;
TangoSupportRotation color_camera_to_display_rotation_; std::map<int, tango_gl::Axis*> markers_;
rtabmap::ScreenRotation color_camera_to_display_rotation_;
std::map<int, PointCloudDrawable*> pointClouds_; std::map<int, PointCloudDrawable*> pointClouds_;
@@ -189,7 +207,8 @@ class Scene {
float g_; float g_;
float b_; float b_;
GLuint fboId_; GLuint fboId_;
GLuint depthTexture_; GLuint rboId_;
GLuint depthTexture_; // 0=objects+occlusion
GLsizei screenWidth_; GLsizei screenWidth_;
GLsizei screenHeight_; GLsizei screenHeight_;
bool doubleTapOn_; bool doubleTapOn_;
+2 -2
View File
@@ -24,8 +24,8 @@ Camera::Camera() {
aspect_ratio_ = 4.0f / 3.0f; aspect_ratio_ = 4.0f / 3.0f;
width_ = 800.0f; width_ = 800.0f;
height_ = 600.0f; height_ = 600.0f;
near_clip_plane_ = 0.2f; near_clip_plane_ = 0.5f;
far_clip_plane_ = 1000.0f; far_clip_plane_ = 50.0f;
ortho_ = false; ortho_ = false;
orthoScale_ = 2.0f; orthoScale_ = 2.0f;
orthoCropFactor_ = -1.0f; orthoCropFactor_ = -1.0f;
+8 -5
View File
@@ -18,11 +18,14 @@
namespace tango_gl { namespace tango_gl {
static const float float_vertices[] = { static const float float_vertices[] = {
0.0f, 0.0f, 0.0f, -1.0f, 1.0f, -1.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f, -1.0f, 1.0f, -1.0f,
1.0f, -1.0f, 0.0f, 0.0f, 0.0f, -1.0f, -1.0f, -1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, 1.0f, -1.0f,
0.0f, 1.0f, -1.0f, -1.0f, -1.0f, 1.0f, -1.0f, 1.0f, 1.0f, -1.0f, 0.0f, 0.0f, 0.0f, -1.0f, -1.0f, -1.0f,
1.0f, 1.0f, -1.0f, 1.0f, -1.0f, -1.0f, 1.0f, -1.0f, -1.0f, -1.0f, 0.0f, 0.0f, 0.0f, 1.0f, -1.0f, -1.0f,
-1.0f, -1.0f, -1.0f, -1.0f, -1.0f, -1.0f, 1.0f, -1.0f}; -1.0f, 1.0f, -1.0f, 1.0f, 1.0f, -1.0f,
1.0f, 1.0f, -1.0f, 1.0f, -1.0f, -1.0f,
1.0f, -1.0f, -1.0f, -1.0f, -1.0f, -1.0f,
-1.0f, -1.0f, -1.0f, -1.0f, 1.0f, -1.0f};
Frustum::Frustum() : Line(3.0f, GL_LINES) { Frustum::Frustum() : Line(3.0f, GL_LINES) {
SetShader(); SetShader();
+18 -11
View File
@@ -43,9 +43,11 @@ const float kCamViewMaxDist = 100.f;
// FOV set up values. // FOV set up values.
// Third and top down camera's FOV is 65 degrees. // Third and top down camera's FOV is 65 degrees.
// First person camera's FOV is 45 degrees. // First person camera's FOV is 85 degrees.
const float kHighFov = 65.0f; const float kHighestFov = 120.0f;
const float kHighFov = 85.0f;
const float kLowFov = 65.0f; const float kLowFov = 65.0f;
const float kLowestFov = 40.0f;
} }
namespace tango_gl { namespace tango_gl {
@@ -111,7 +113,7 @@ void GestureCamera::OnTouchEvent(int touch_count, TouchEvent event, float x0,
if(camera_type_ == kFirstPerson) if(camera_type_ == kFirstPerson)
{ {
this->SetFieldOfView(tango_gl::util::Clamp(cam_start_fov_ + dist * kZoomSpeed*10.0f, 45, 90)); this->SetFieldOfView(tango_gl::util::Clamp(cam_start_fov_ + dist * kZoomSpeed*10.0f, kLowestFov, kHighestFov));
} }
else else
{ {
@@ -179,8 +181,9 @@ void GestureCamera::SetCameraType(CameraType camera_index) {
camera_type_ = camera_index; camera_type_ = camera_index;
switch (camera_index) { switch (camera_index) {
case kFirstPerson: case kFirstPerson:
SetOrthoMode(false); SetOrthoMode(false);
SetFieldOfView(kLowFov); SetFieldOfView(kLowestFov);
SetNearFarClipPlanes(0.25, 25);
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;
@@ -193,14 +196,15 @@ void GestureCamera::SetCameraType(CameraType camera_index) {
break; break;
case kThirdPerson: case kThirdPerson:
case kThirdPersonFollow: case kThirdPersonFollow:
SetOrthoMode(false); SetOrthoMode(false);
SetFieldOfView(kHighFov); SetFieldOfView(kLowFov);
SetNearFarClipPlanes(1, 50);
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_ = camera_index==kThirdPersonFollow?kThirdPersonFollowCameraDist:kThirdPersonCameraDist;
anchor_offset_ = glm::vec3(0.0f,0.0f,0.0f); anchor_offset_ = glm::vec3(0.0f,0.0f,0.0f);
cam_cur_angle_.x = -M_PI / 6.0f; cam_cur_angle_.x = -M_PI / 12.0f;
cam_cur_angle_.y = kThirdPersonFollow?0:M_PI / 4.0f; cam_cur_angle_.y = kThirdPersonFollow?0:M_PI / 2.0f;
cam_cur_target_rot_ = glm::quat(1,0,0,0); cam_cur_target_rot_ = glm::quat(1,0,0,0);
StartCameraToCurrentTransform(); StartCameraToCurrentTransform();
break; break;
@@ -208,7 +212,8 @@ 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));
SetOrthoMode(false); SetOrthoMode(false);
SetFieldOfView(kHighFov); SetFieldOfView(kLowFov);
SetNearFarClipPlanes(1, 50);
cam_cur_dist_ = kTopDownCameraDist; cam_cur_dist_ = kTopDownCameraDist;
anchor_offset_ = glm::vec3(0.0f,0.0f,0.0f); 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;
@@ -222,6 +227,8 @@ void GestureCamera::SetCameraType(CameraType camera_index) {
SetOrthoMode(true); SetOrthoMode(true);
SetOrthoScale(kTopDownCameraDist); SetOrthoScale(kTopDownCameraDist);
SetOrthoCropFactor(-1.0f); SetOrthoCropFactor(-1.0f);
SetFieldOfView(kLowFov);
SetNearFarClipPlanes(1, 50);
cam_cur_dist_ = kTopDownCameraDist; cam_cur_dist_ = kTopDownCameraDist;
anchor_offset_ = glm::vec3(0.0f,0.0f,0.0f); 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;
+8 -4
View File
@@ -31,13 +31,17 @@ Grid::Grid(float density, int qx, int qy) : Line(1.0f, GL_LINES) {
// Horizontal line. // Horizontal line.
for (int i = 0; i < (qy + 1); i++) { for (int i = 0; i < (qy + 1); i++) {
vec_vertices_.push_back(glm::vec3(-width, 0.0f, -height + i * density)); for (int j = 0; j < (qx + 1); j++) {
vec_vertices_.push_back(glm::vec3(width, 0.0f, -height + i * density)); vec_vertices_.push_back(glm::vec3(-width + j*density, 0.0f, -height + i * density));
vec_vertices_.push_back(glm::vec3(-width+ + (j+1)*density, 0.0f, -height + i * density));
}
} }
for (int i = 0; i < (qx + 1); i++) { for (int i = 0; i < (qx + 1); i++) {
vec_vertices_.push_back(glm::vec3(-width + i * density, 0.0f, -height)); for (int j = 0; j < (qy + 1); j++) {
vec_vertices_.push_back(glm::vec3(-width + i * density, 0.0f, height)); vec_vertices_.push_back(glm::vec3(-width + i * density, 0.0f, -height + j*density));
vec_vertices_.push_back(glm::vec3(-width + i * density, 0.0f, -height + (j+1)*density));
}
} }
} }
} // namespace tango_gl } // namespace tango_gl
@@ -18,7 +18,10 @@
#define TANGO_GL_TEXTURE_H_ #define TANGO_GL_TEXTURE_H_
#include <errno.h> #include <errno.h>
#ifdef __ANDROID__
#include <png.h> #include <png.h>
#endif
#include "tango-gl/util.h" #include "tango-gl/util.h"
@@ -30,11 +33,15 @@ class Texture {
Texture& operator=(const Texture&) = delete; Texture& operator=(const Texture&) = delete;
~Texture(); ~Texture();
#ifdef __ANDROID__
bool LoadFromPNG(const char* file_path); bool LoadFromPNG(const char* file_path);
#endif
GLuint GetTextureID() const; GLuint GetTextureID() const;
private: private:
#ifdef __ANDROID__
png_uint_32 width_, height_; png_uint_32 width_, height_;
#endif
int bit_depth_, color_type_; int bit_depth_, color_type_;
char* byte_data_; char* byte_data_;
GLuint texture_id_; GLuint texture_id_;
@@ -21,11 +21,16 @@
#define GL_VERTEX_PROGRAM_POINT_SIZE 0x8642 #define GL_VERTEX_PROGRAM_POINT_SIZE 0x8642
#include <stdlib.h> #include <stdlib.h>
#ifdef __ANDROID__
#include <jni.h> #include <jni.h>
#include <android/log.h> #include <android/log.h>
#include <GLES2/gl2.h> #include <GLES2/gl2.h>
#include <GLES2/gl2ext.h> #include <GLES2/gl2ext.h>
#include <tango_support_api.h> #else // __APPLE__
#include <OpenGLES/ES2/gl.h>
#include <OpenGLES/ES2/glext.h>
#include <syslog.h>
#endif
#include "glm/glm.hpp" #include "glm/glm.hpp"
#include "glm/gtc/matrix_transform.hpp" #include "glm/gtc/matrix_transform.hpp"
@@ -34,16 +39,28 @@
#include "glm/gtx/matrix_decompose.hpp" #include "glm/gtx/matrix_decompose.hpp"
#define LOG_TAG "rtabmap" #define LOG_TAG "rtabmap"
#ifdef DISABLE_LOG #if defined(DISABLE_LOG)
#define LOGD(...) ; #define LOGD(...) ;
#define LOGI(...) ; #define LOGI(...) ;
#define LOGW(...) ; #define LOGW(...) ;
#else #else
#ifdef __APPLE__
#define LOGD(...) fprintf(stderr, __VA_ARGS__); fprintf(stderr, "\n")
#define LOGI(...) fprintf(stderr, __VA_ARGS__); fprintf(stderr, "\n")
#define LOGW(...) fprintf(stderr, __VA_ARGS__); fprintf(stderr, "\n")
#else
#define LOGD(...) __android_log_print(ANDROID_LOG_DEBUG,LOG_TAG,__VA_ARGS__) #define LOGD(...) __android_log_print(ANDROID_LOG_DEBUG,LOG_TAG,__VA_ARGS__)
#define LOGI(...) __android_log_print(ANDROID_LOG_INFO,LOG_TAG,__VA_ARGS__) #define LOGI(...) __android_log_print(ANDROID_LOG_INFO,LOG_TAG,__VA_ARGS__)
#define LOGW(...) __android_log_print(ANDROID_LOG_WARN,LOG_TAG,__VA_ARGS__) #define LOGW(...) __android_log_print(ANDROID_LOG_WARN,LOG_TAG,__VA_ARGS__)
#endif #endif
#endif
#ifdef __APPLE__
#define LOGE(...) fprintf(stderr, __VA_ARGS__); fprintf(stderr, "\n")
#define LOGF(...) fprintf(stderr, __VA_ARGS__); fprintf(stderr, "\n")
#else
#define LOGE(...) __android_log_print(ANDROID_LOG_ERROR,LOG_TAG,__VA_ARGS__) #define LOGE(...) __android_log_print(ANDROID_LOG_ERROR,LOG_TAG,__VA_ARGS__)
#define LOGF(...) __android_log_print(ANDROID_LOG_FATAL,LOG_TAG,__VA_ARGS__)
#endif
#ifndef M_PI #ifndef M_PI
#define M_PI 3.1415926f #define M_PI 3.1415926f
@@ -84,32 +101,6 @@ namespace util {
glm::vec3 ApplyTransform(const glm::mat4& mat, const glm::vec3& vec); glm::vec3 ApplyTransform(const glm::mat4& mat, const glm::vec3& vec);
// Get the Android rotation integer value from color camera to display.
// This function is used to compute the orientation difference to handle
// the portrait and landscape mode for color camera display.
//
// @param display: integer value of display orientation, values available
// are 0, 1, 2 ,3. Followed by Android display orientation standard:
// https://developer.android.com/reference/android/view/Display.html#getRotation()
// @param color_camera: integer value of color camera oreintation, values
// available are 0, 90, 180, 270. Followed by Android camera orientation
// standard:
// https://developer.android.com/reference/android/hardware/Camera.CameraInfo.html#orientation
TangoSupportRotation GetAndroidRotationFromColorCameraToDisplay(
int display_rotation, int color_camera_rotation);
// Get the Android rotation integer value from color camera to display.
// This function is used to compute the orientation difference to handle
// the portrait and landscape mode for color camera display.
//
// @param display: the device display orientation.
// @param color_camera: integer value of color camera oreintation, values
// available are 0, 90, 180, 270. Followed by Android camera orientation
// standard:
// https://developer.android.com/reference/android/hardware/Camera.CameraInfo.html#orientation
TangoSupportRotation GetAndroidRotationFromColorCameraToDisplay(
TangoSupportRotation display_rotation, int color_camera_rotation);
} // namespace util } // namespace util
} // namespace tango_gl } // namespace tango_gl
#endif // TANGO_GL_RENDERER_GL_UTIL #endif // TANGO_GL_RENDERER_GL_UTIL
+1 -1
View File
@@ -57,7 +57,7 @@ Quad::Quad() {
Quad::~Quad() { glDeleteShader(shader_program_); } Quad::~Quad() { glDeleteShader(shader_program_); }
void Quat::SetTextureId(GLuint texture_id) { texture_id_ = texture_id; } void Quad::SetTextureId(GLuint texture_id) { texture_id_ = texture_id; }
void Quad::Render(const glm::mat4& projection_mat, void Quad::Render(const glm::mat4& projection_mat,
const glm::mat4& view_mat) const { const glm::mat4& view_mat) const {
+4 -2
View File
@@ -34,11 +34,13 @@ static int RoundUpPowerOfTwo(int w) {
} }
Texture::Texture(const char* file_path) { Texture::Texture(const char* file_path) {
#ifdef __ANDROID__
if (!LoadFromPNG(file_path)) { if (!LoadFromPNG(file_path)) {
LOGE("Texture initialing error"); LOGE("Texture initialing error");
} }
#endif
} }
#ifdef __ANDROID__
bool Texture::LoadFromPNG(const char* file_path) { bool Texture::LoadFromPNG(const char* file_path) {
FILE* file = fopen(file_path, "rb"); FILE* file = fopen(file_path, "rb");
@@ -94,7 +96,7 @@ bool Texture::LoadFromPNG(const char* file_path) {
return true; return true;
} }
#endif
GLuint Texture::GetTextureID() const { return texture_id_; } GLuint Texture::GetTextureID() const { return texture_id_; }
Texture::~Texture() { Texture::~Texture() {
-19
View File
@@ -238,23 +238,4 @@ glm::vec3 util::ApplyTransform(const glm::mat4& mat, const glm::vec3& vec) {
return glm::vec3(mat * glm::vec4(vec, 1.0f)); return glm::vec3(mat * glm::vec4(vec, 1.0f));
} }
TangoSupportRotation util::GetAndroidRotationFromColorCameraToDisplay(
int display_rotation, int color_camera_rotation) {
TangoSupportRotation r =
static_cast<TangoSupportRotation>(display_rotation);
return util::GetAndroidRotationFromColorCameraToDisplay(
r, color_camera_rotation);
}
TangoSupportRotation util::GetAndroidRotationFromColorCameraToDisplay(
TangoSupportRotation display_rotation, int color_camera_rotation) {
int color_camera_n = NormalizedColorCameraRotation(color_camera_rotation);
int ret = static_cast<int>(display_rotation) - color_camera_n;
if (ret < 0) {
ret += 4;
}
return static_cast<TangoSupportRotation>(ret % 4);
}
} // namespace tango_gl } // namespace tango_gl
+110 -15
View File
@@ -28,8 +28,6 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#ifndef UTIL_H_ #ifndef UTIL_H_
#define UTIL_H_ #define UTIL_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 <rtabmap/core/CameraModel.h>
@@ -39,13 +37,20 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include <pcl/Vertices.h> #include <pcl/Vertices.h>
#include <pcl/pcl_base.h> #include <pcl/pcl_base.h>
namespace rtabmap {
class LogHandler : public UEventsHandler class LogHandler : public UEventsHandler
{ {
public: public:
LogHandler() LogHandler()
{ {
ULogger::setLevel(ULogger::kDebug); #ifdef DISABLE_LOG
ULogger::setEventLevel(ULogger::kDebug); ULogger::setLevel(ULogger::kWarning);
ULogger::setEventLevel(ULogger::kWarning);
#else
ULogger::setLevel(ULogger::kDebug);
ULogger::setEventLevel(ULogger::kDebug);
#endif
ULogger::setPrintThreadId(true); ULogger::setPrintThreadId(true);
registerToEventsManager(); registerToEventsManager();
@@ -53,31 +58,39 @@ public:
protected: protected:
virtual bool handleEvent(UEvent * event) virtual bool handleEvent(UEvent * event)
{ {
if(event->getClassName().compare("ULogEvent") == 0) if(event->getClassName().compare("ULogEvent") == 0)
{ {
ULogEvent * logEvent = (ULogEvent*)event; ULogEvent * logEvent = (ULogEvent*)event;
if(logEvent->getCode() == ULogger::kDebug) if(logEvent->getCode() == ULogger::kDebug)
{ {
LOGD(logEvent->getMsg().c_str()); LOGD("%s", logEvent->getMsg().c_str());
} }
else if(logEvent->getCode() == ULogger::kInfo) else if(logEvent->getCode() == ULogger::kInfo)
{ {
LOGI(logEvent->getMsg().c_str()); LOGI("%s", logEvent->getMsg().c_str());
} }
else if(logEvent->getCode() == ULogger::kWarning) else if(logEvent->getCode() == ULogger::kWarning)
{ {
LOGW(logEvent->getMsg().c_str()); LOGW("%s", logEvent->getMsg().c_str());
} }
else if(logEvent->getCode() >= ULogger::kError) else if(logEvent->getCode() >= ULogger::kError)
{ {
LOGE(logEvent->getMsg().c_str()); LOGE("%s", logEvent->getMsg().c_str());
}
else if(logEvent->getCode() >= ULogger::kFatal)
{
LOGF("%s", logEvent->getMsg().c_str());
} }
} }
return false; return false;
} }
}; };
static const rtabmap::Transform optical_T_opengl(
1.0f, 0.0f, 0.0f, 0.0f,
0.0f, -1.0f, 0.0f, 0.0f,
0.0f, 0.0f, -1.0f, 0.0f);
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,
@@ -88,20 +101,25 @@ static const rtabmap::Transform rtabmap_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);
static const rtabmap::Transform tango_device_T_rtabmap_device( static const rtabmap::Transform tango_device_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 tango_world_T_rtabmap_world(
0.0f, -1.0f, 0.0f, 0.0f,
1.0f, 0.0f, 0.0f, 0.0f,
0.0f, 0.0f, 1.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_device_T_opengl_device( static const rtabmap::Transform rtabmap_world_T_opengl_world(
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);
inline glm::mat4 glmFromTransform(const rtabmap::Transform & transform) inline glm::mat4 glmFromTransform(const rtabmap::Transform & transform)
{ {
@@ -173,4 +191,81 @@ public:
cv::Mat texture; cv::Mat texture;
}; };
typedef enum {
/// Not apply any rotation.
ROTATION_IGNORED = -1,
/// 0 degree rotation (natural orientation)
ROTATION_0 = 0,
/// 90 degree rotation.
ROTATION_90 = 1,
/// 180 degree rotation.
ROTATION_180 = 2,
/// 270 degree rotation.
ROTATION_270 = 3
} ScreenRotation;
inline int NormalizedColorCameraRotation(int camera_rotation) {
int camera_n = 0;
switch (camera_rotation) {
case 90:
camera_n = 1;
break;
case 180:
camera_n = 2;
break;
case 270:
camera_n = 3;
break;
default:
camera_n = 0;
break;
}
return camera_n;
}
// Get the Android rotation integer value from color camera to display.
// This function is used to compute the orientation difference to handle
// the portrait and landscape mode for color camera display.
//
// @param display: the device display orientation.
// @param color_camera: integer value of color camera oreintation, values
// available are 0, 90, 180, 270. Followed by Android camera orientation
// standard:
// https://developer.android.com/reference/android/hardware/Camera.CameraInfo.html#orientation
inline ScreenRotation GetAndroidRotationFromColorCameraToDisplay(
ScreenRotation display_rotation, int color_camera_rotation) {
int color_camera_n = NormalizedColorCameraRotation(color_camera_rotation);
int ret = static_cast<int>(display_rotation) - color_camera_n;
if (ret < 0) {
ret += 4;
}
return static_cast<ScreenRotation>(ret % 4);
}
// Get the Android rotation integer value from color camera to display.
// This function is used to compute the orientation difference to handle
// the portrait and landscape mode for color camera display.
//
// @param display: integer value of display orientation, values available
// are 0, 1, 2 ,3. Followed by Android display orientation standard:
// https://developer.android.com/reference/android/view/Display.html#getRotation()
// @param color_camera: integer value of color camera orientation, values
// available are 0, 90, 180, 270. Followed by Android camera orientation
// standard:
// https://developer.android.com/reference/android/hardware/Camera.CameraInfo.html#orientation
inline ScreenRotation GetAndroidRotationFromColorCameraToDisplay(
int display_rotation, int color_camera_rotation) {
ScreenRotation r =
static_cast<ScreenRotation>(display_rotation);
return GetAndroidRotationFromColorCameraToDisplay(
r, color_camera_rotation);
}
}
#endif /* UTIL_H_ */ #endif /* UTIL_H_ */
+1
View File
@@ -0,0 +1 @@
*.jar
Binary file not shown.

After

Width:  |  Height:  |  Size: 9.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.0 KiB

+36 -10
View File
@@ -27,6 +27,26 @@
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="match_parent" android:layout_height="match_parent"
android:fitsSystemWindows="true"> android:fitsSystemWindows="true">
<ImageButton
android:id="@+id/start_button"
android:layout_width="100dp"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:layout_centerHorizontal="true"
android:src="@drawable/start96"
android:background="@null"
android:layout_marginBottom="10dp" />
<ImageButton
android:id="@+id/stop_button"
android:layout_width="100dp"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:layout_centerHorizontal="true"
android:src="@drawable/stop96"
android:background="@null"
android:layout_marginBottom="10dp" />
<ToggleButton <ToggleButton
android:id="@+id/wireframe_button" android:id="@+id/wireframe_button"
@@ -80,16 +100,6 @@
android:text="@string/camera_button" android:text="@string/camera_button"
android:spinnerMode="dropdown"/> android:spinnerMode="dropdown"/>
<ToggleButton
android:id="@+id/pause_button"
android:layout_width="100dp"
android:layout_height="wrap_content"
android:layout_marginRight="5dp"
android:layout_alignParentTop="true"
android:layout_marginTop="10dp"
android:layout_alignParentRight="true"
android:textOff="@string/pause"
android:textOn="@string/resume" />
<Button <Button
android:id="@+id/button_shareToSketchfab" android:id="@+id/button_shareToSketchfab"
@@ -138,7 +148,23 @@
android:paddingBottom="10dp" android:paddingBottom="10dp"
android:progressDrawable="@drawable/custom_seekbar" /> android:progressDrawable="@drawable/custom_seekbar" />
<Button
android:id="@+id/button_library"
android:layout_width="match_parent"
android:layout_height="100dp"
android:layout_centerHorizontal="true"
android:layout_gravity="top"
android:layout_marginTop="100dp"
android:text="@string/library" />
<Button
android:id="@+id/button_new_scan"
android:layout_width="match_parent"
android:layout_height="100dp"
android:layout_alignLeft="@+id/button_library"
android:layout_below="@+id/button_library"
android:layout_marginTop="20dp"
android:text="@string/new_scan" />
</RelativeLayout> </RelativeLayout>
</RelativeLayout> </RelativeLayout>
+40 -1
View File
@@ -1,5 +1,13 @@
<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android"> <PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android">
<ListPreference
android:key="@string/pref_key_camera_driver"
android:title="@string/pref_title_camera_driver"
android:summary="@string/pref_summary_camera_driver"
android:entries="@array/pref_camera_driver_keys"
android:entryValues="@array/pref_camera_driver_values"
android:defaultValue="@string/pref_default_camera_driver"/>
<PreferenceCategory <PreferenceCategory
android:title="@string/pref_title_rendering"> android:title="@string/pref_title_rendering">
<ListPreference <ListPreference
@@ -78,7 +86,7 @@
android:title="@string/pref_title_mapping_sub" android:title="@string/pref_title_mapping_sub"
android:summary="@string/pref_summary_mapping" android:summary="@string/pref_summary_mapping"
android:persistent="false"> android:persistent="false">
<com.introlab.rtabmap.CustomSwitchPreference <com.introlab.rtabmap.CustomSwitchPreference
android:key="@string/pref_key_append" android:key="@string/pref_key_append"
android:title="@string/pref_title_append" android:title="@string/pref_title_append"
@@ -90,6 +98,18 @@
android:summary="@string/pref_summary_resolution" android:summary="@string/pref_summary_resolution"
android:defaultValue="@string/pref_default_resolution"/> android:defaultValue="@string/pref_default_resolution"/>
<com.introlab.rtabmap.CustomSwitchPreference <com.introlab.rtabmap.CustomSwitchPreference
android:key="@string/pref_key_depth_from_motion"
android:title="@string/pref_title_depth_from_motion"
android:summary="@string/pref_summary_depth_from_motion"
android:defaultValue="@string/pref_default_depth_from_motion"/>
<ListPreference
android:key="@string/pref_key_arcore_localization_filtering_speed"
android:title="@string/pref_title_arcore_localization_filtering_speed"
android:summary="@string/pref_summary_arcore_localization_filtering_speed"
android:entries="@array/pref_arcore_localization_filtering_speed_keys"
android:entryValues="@array/pref_arcore_localization_filtering_speed_values"
android:defaultValue="@string/pref_default_arcore_localization_filtering_speed"/>
<com.introlab.rtabmap.CustomSwitchPreference
android:key="@string/pref_key_smoothing" android:key="@string/pref_key_smoothing"
android:title="@string/pref_title_smoothing" android:title="@string/pref_title_smoothing"
android:summary="@string/pref_summary_smoothing" android:summary="@string/pref_summary_smoothing"
@@ -191,6 +211,20 @@
android:title="@string/pref_title_optimize_end" android:title="@string/pref_title_optimize_end"
android:summary="@string/pref_summary_optimize_end" android:summary="@string/pref_summary_optimize_end"
android:defaultValue="@string/pref_default_optimize_end"/> android:defaultValue="@string/pref_default_optimize_end"/>
<ListPreference
android:key="@string/pref_key_marker_detection"
android:title="@string/pref_title_marker_detection"
android:summary="@string/pref_summary_marker_detection"
android:entries="@array/pref_marker_detection_keys"
android:entryValues="@array/pref_marker_detection_values"
android:defaultValue="@string/pref_default_marker_detection"/>
<ListPreference
android:key="@string/pref_key_marker_detection_depth_error"
android:title="@string/pref_title_marker_detection_depth_error"
android:summary="@string/pref_summary_marker_detection_depth_error"
android:entries="@array/pref_marker_detection_depth_error_keys"
android:entryValues="@array/pref_marker_detection_depth_error_values"
android:defaultValue="@string/pref_default_marker_detection_depth_error"/>
</PreferenceCategory> </PreferenceCategory>
<PreferenceCategory <PreferenceCategory
android:title="@string/pref_title_mapping_database"> android:title="@string/pref_title_mapping_database">
@@ -209,6 +243,11 @@
android:title="@string/pref_title_gps_saved" android:title="@string/pref_title_gps_saved"
android:summary="@string/pref_summary_gps_saved" android:summary="@string/pref_summary_gps_saved"
android:defaultValue="@string/pref_default_gps_saved"/> android:defaultValue="@string/pref_default_gps_saved"/>
<com.introlab.rtabmap.CustomSwitchPreference
android:key="@string/pref_key_env_sensors_saved"
android:title="@string/pref_title_env_sensors_saved"
android:summary="@string/pref_summary_env_sensors_saved"
android:defaultValue="@string/pref_default_env_sensors_saved"/>
<com.introlab.rtabmap.CustomSwitchPreference <com.introlab.rtabmap.CustomSwitchPreference
android:key="@string/pref_key_db_in_memory" android:key="@string/pref_key_db_in_memory"
android:title="@string/pref_title_db_in_memory" android:title="@string/pref_title_db_in_memory"
+4 -13
View File
@@ -62,20 +62,11 @@
android:checked="true" android:checked="true"
android:text="Draft Mode" /> android:text="Draft Mode" />
<LinearLayout <Button
android:id="@+id/button_ok"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="0dip" android:layout_height="wrap_content"
android:layout_weight="1" android:text="Upload" />
android:gravity="right|bottom"
android:orientation="horizontal" >
<Button
android:id="@+id/button_ok"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="0.06"
android:text="Upload" />
</LinearLayout>
</LinearLayout> </LinearLayout>
</ScrollView> </ScrollView>
+22 -21
View File
@@ -7,26 +7,12 @@
<item android:id="@+id/mesh" android:title="Mesh" /> <item android:id="@+id/mesh" android:title="Mesh" />
<item android:id="@+id/texture_mesh" android:checked="true" android:title="Texture Mesh" /> <item android:id="@+id/texture_mesh" android:checked="true" android:title="Texture Mesh" />
</group> </group>
<item android:id="@+id/save" android:title="Save" android:showAsAction="ifRoom"/>
<item android:id="@+id/new_scan" android:title="New Scan"/>
<item android:id="@+id/export" android:showAsAction="ifRoom" android:title="Export"> <item android:id="@+id/open" android:title="Library" android:showAsAction="ifRoom"/>
<menu> <item android:id="@+id/save" android:title="Save"/>
<item android:id="@+id/export_point_cloud_menu" android:title="Point Cloud">
<menu>
<item android:id="@+id/export_point_cloud" android:title="Current Density" />
<item android:id="@+id/export_point_cloud_highrez" android:title="Max Density" />
</menu>
</item>
<item android:id="@+id/export_optimized_mesh_menu" android:title="Optimized Mesh..." >
<menu>
<item android:id="@+id/export_optimized_mesh" android:title="Colored Mesh" />
<item android:id="@+id/export_optimized_mesh_texture" android:title="Textured Mesh" />
</menu>
</item>
</menu>
</item>
<item android:id="@+id/post_processing" android:title="Optimize" android:showAsAction="ifRoom"> <item android:id="@+id/post_processing" android:title="Optimize">
<menu> <menu>
<item android:id="@+id/post_processing_standard" android:title="Standard Optimization" /> <item android:id="@+id/post_processing_standard" android:title="Standard Optimization" />
<item android:id="@+id/post_processing_advanced" android:title="Advanced..." > <item android:id="@+id/post_processing_advanced" android:title="Advanced..." >
@@ -43,7 +29,22 @@
</menu> </menu>
</item> </item>
<item android:id="@+id/open" android:title="Open" android:showAsAction="ifRoom"/> <item android:id="@+id/export" android:title="Assemble">
<menu>
<item android:id="@+id/export_point_cloud_menu" android:title="Point Cloud">
<menu>
<item android:id="@+id/export_point_cloud" android:title="Current Density" />
<item android:id="@+id/export_point_cloud_highrez" android:title="Max Density" />
</menu>
</item>
<item android:id="@+id/export_optimized_mesh_menu" android:title="Optimized Mesh..." >
<menu>
<item android:id="@+id/export_optimized_mesh" android:title="Colored Mesh" />
<item android:id="@+id/export_optimized_mesh_texture" android:title="Textured Mesh" />
</menu>
</item>
</menu>
</item>
<item android:id="@+id/menu_rendering_settings" android:title="Visibility..."> <item android:id="@+id/menu_rendering_settings" android:title="Visibility...">
<menu > <menu >
@@ -68,7 +69,7 @@
</menu> </menu>
</item> </item>
<item android:id="@+id/settings" android:title="Settings"/> <item android:id="@+id/settings" android:title="Settings"/>
<item android:id="@+id/reset" android:title="Reset"/> <item android:id="@+id/resume" android:title="Resume"/>
<item android:id="@+id/about" android:title="About"/> <item android:id="@+id/about" android:title="About"/>
</group> </group>
</menu> </menu>
+3 -4
View File
@@ -1,4 +1,3 @@
<resources>
<resources> <dimen name="image_width">150dp</dimen>
<dimen name="image_width">150dp</dimen> </resources>
</resources>
+173 -33
View File
@@ -9,15 +9,17 @@
<string name="status">"Status: "</string> <string name="status">"Status: "</string>
<string name="words">"Words: "</string> <string name="words">"Words: "</string>
<string name="camera_button">First View</string> <string name="camera_button">First View</string>
<string name="pause">Pause</string> <string name="library">Library</string>
<string name="resume">Resume</string> <string name="new_scan">New Scan</string>
<string name="pause">Stop</string>
<string name="resume">Start</string>
<string name="backface_on">Backface</string> <string name="backface_on">Backface</string>
<string name="backface_off">Backface</string> <string name="backface_off">Backface</string>
<string name="light_on">Lighting</string> <string name="light_on">Lighting</string>
<string name="light_off">Lighting</string> <string name="light_off">Lighting</string>
<string name="wireframe">Wireframe</string> <string name="wireframe">Wireframe</string>
<string name="close_visualization">Close Visualization</string> <string name="close_visualization">Close Visualization</string>
<string name="save_to_file">Export to File&#8230;</string> <string name="save_to_file">Export OBJ/PLY&#8230;</string>
<string name="share_to_sketchfab">Share to Sketchfab&#8230;</string> <string name="share_to_sketchfab">Share to Sketchfab&#8230;</string>
<string name="start">Start</string> <string name="start">Start</string>
<string name="nodes">"Nodes (WM): "</string> <string name="nodes">"Nodes (WM): "</string>
@@ -36,6 +38,7 @@
<string name="fps">"FPS (rendering): "</string> <string name="fps">"FPS (rendering): "</string>
<string name="distance">"Distance travelled: "</string> <string name="distance">"Distance travelled: "</string>
<string name="gps">"GPS (long,lat,alt,bearing,err): "</string> <string name="gps">"GPS (long,lat,alt,bearing,err): "</string>
<string name="env_sensors">"Sensors: "</string>
<string name="time">"Time: "</string> <string name="time">"Time: "</string>
<!-- Preference keys: BEGIN --> <!-- Preference keys: BEGIN -->
@@ -48,7 +51,7 @@
<string name="pref_key_remove_button">pref_key_remove_button</string> <string name="pref_key_remove_button">pref_key_remove_button</string>
<string name="pref_key_reset_button">pref_key_reset_button</string> <string name="pref_key_reset_button">pref_key_reset_button</string>
<string name="pref_key_density">pref_key_density</string> <string name="pref_key_density">pref_key_density</string>
<string name="pref_default_density">1</string> <string name="pref_default_density">2</string>
<string name="pref_key_min_depth">pref_key_min_depth</string> <string name="pref_key_min_depth">pref_key_min_depth</string>
<string name="pref_default_min_depth">0</string> <string name="pref_default_min_depth">0</string>
<string name="pref_key_depth">pref_key_depth</string> <string name="pref_key_depth">pref_key_depth</string>
@@ -72,16 +75,22 @@
<string name="pref_key_resolution">pref_key_resolution</string> <string name="pref_key_resolution">pref_key_resolution</string>
<string name="pref_default_resolution">false</string> <string name="pref_default_resolution">false</string>
<string name="pref_key_smoothing">pref_key_smoothing</string> <string name="pref_key_smoothing">pref_key_smoothing</string>
<string name="pref_default_smoothing">true</string> <string name="pref_default_smoothing">false</string>
<string name="pref_key_fisheye">pref_key_fisheye</string> <string name="pref_key_fisheye">pref_key_fisheye</string>
<string name="pref_default_fisheye">false</string> <string name="pref_default_fisheye">false</string>
<string name="pref_key_camera_driver">pref_key_camera_driver</string>
<string name="pref_default_camera_driver">-1</string>
<string name="pref_key_depth_from_motion">pref_key_depth_from_motion</string>
<string name="pref_default_depth_from_motion">false</string>
<string name="pref_key_arcore_localization_filtering_speed">pref_key_arcore_localization_filtering_speed</string>
<string name="pref_default_arcore_localization_filtering_speed">1</string>
<string name="pref_key_update_rate">pref_key_update_rate</string> <string name="pref_key_update_rate">pref_key_update_rate</string>
<string name="pref_default_update_rate">1</string> <string name="pref_default_update_rate">1</string>
<string name="pref_key_max_speed">pref_key_max_speed</string> <string name="pref_key_max_speed">pref_key_max_speed</string>
<string name="pref_default_max_speed">0</string> <string name="pref_default_max_speed">0</string>
<string name="pref_key_time_thr">pref_key_time_thr</string> <string name="pref_key_time_thr">pref_key_time_thr</string>
<string name="pref_default_time_thr">1000</string> <string name="pref_default_time_thr">0</string>
<string name="pref_key_mem_thr">pref_key_mem_thr</string> <string name="pref_key_mem_thr">pref_key_mem_thr</string>
<string name="pref_default_mem_thr">0</string> <string name="pref_default_mem_thr">0</string>
<string name="pref_key_loop_thr">pref_key_loop_thr</string> <string name="pref_key_loop_thr">pref_key_loop_thr</string>
@@ -91,7 +100,7 @@
<string name="pref_key_min_inliers">pref_key_min_inliers</string> <string name="pref_key_min_inliers">pref_key_min_inliers</string>
<string name="pref_default_min_inliers">25</string> <string name="pref_default_min_inliers">25</string>
<string name="pref_key_opt_error">pref_key_opt_error</string> <string name="pref_key_opt_error">pref_key_opt_error</string>
<string name="pref_default_opt_error">2</string> <string name="pref_default_opt_error">1</string>
<string name="pref_key_features_voc">pref_key_features_voc</string> <string name="pref_key_features_voc">pref_key_features_voc</string>
<string name="pref_default_features_voc">200</string> <string name="pref_default_features_voc">200</string>
<string name="pref_key_features">pref_key_features</string> <string name="pref_key_features">pref_key_features</string>
@@ -102,12 +111,18 @@
<string name="pref_default_optimizer">2</string> <string name="pref_default_optimizer">2</string>
<string name="pref_key_optimize_end">pref_key_optimize_end</string> <string name="pref_key_optimize_end">pref_key_optimize_end</string>
<string name="pref_default_optimize_end">true</string> <string name="pref_default_optimize_end">true</string>
<string name="pref_key_marker_detection">pref_key_marker_detection</string>
<string name="pref_default_marker_detection">-1</string>
<string name="pref_key_marker_detection_depth_error">pref_key_marker_detection_depth_error</string>
<string name="pref_default_marker_detection_depth_error">0.1</string>
<string name="pref_key_keep_all_db">pref_key_keep_all_db</string> <string name="pref_key_keep_all_db">pref_key_keep_all_db</string>
<string name="pref_default_keep_all_db">true</string> <string name="pref_default_keep_all_db">true</string>
<string name="pref_key_raw_scan_saved">pref_key_raw_scan_saved</string> <string name="pref_key_raw_scan_saved">pref_key_raw_scan_saved</string>
<string name="pref_default_raw_scan_saved">false</string> <string name="pref_default_raw_scan_saved">false</string>
<string name="pref_key_gps_saved">pref_key_gps_saved</string> <string name="pref_key_gps_saved">pref_key_gps_saved</string>
<string name="pref_default_gps_saved">false</string> <string name="pref_default_gps_saved">false</string>
<string name="pref_key_env_sensors_saved">pref_key_env_sensors_saved</string>
<string name="pref_default_env_sensors_saved">false</string>
<string name="pref_key_db_in_memory">pref_key_db_in_memory</string> <string name="pref_key_db_in_memory">pref_key_db_in_memory</string>
<string name="pref_default_db_in_memory">false</string> <string name="pref_default_db_in_memory">false</string>
@@ -149,7 +164,7 @@
<string name="pref_title_triangle">Mesh Triangle Size</string> <string name="pref_title_triangle">Mesh Triangle Size</string>
<string name="pref_summary_triangle">Size in pixels of the polygons created from the depth image.</string> <string name="pref_summary_triangle">Size in pixels of the polygons created from the depth image.</string>
<string name="pref_title_rendering_texture_decimation">Texture Resolution</string> <string name="pref_title_rendering_texture_decimation">Texture Resolution</string>
<string name="pref_summary_rendering_texture_decimation">Resolution of the texture for online rendering. This doesn\'t affect Export results.</string> <string name="pref_summary_rendering_texture_decimation">Resolution of the texture for online rendering. This doesn\'t affect Assembling results.</string>
<string name="pref_title_min_depth">Min Depth</string> <string name="pref_title_min_depth">Min Depth</string>
<string name="pref_summary_min_depth">Points under the minimum depth are not rendered.</string> <string name="pref_summary_min_depth">Points under the minimum depth are not rendered.</string>
<string name="pref_title_depth">Max Depth</string> <string name="pref_title_depth">Max Depth</string>
@@ -310,6 +325,12 @@
<string name="pref_summary_mapping">Advanced mapping parameters for fine tuning.</string> <string name="pref_summary_mapping">Advanced mapping parameters for fine tuning.</string>
<string name="pref_title_mapping_core">Core</string> <string name="pref_title_mapping_core">Core</string>
<string name="pref_title_mapping_database">Database</string> <string name="pref_title_mapping_database">Database</string>
<string name="pref_title_camera_driver">Camera Driver</string>
<string name="pref_summary_camera_driver">AR sdk used for capturing 6DoF poses and images. A TOF camera is required to record a 3D model.</string>
<string name="pref_title_depth_from_motion">Depth From Motion</string>
<string name="pref_summary_depth_from_motion">Use ARCore\'s depth API to compute depth image from motion. If the phone has a TOF camera and is supported by ARCore, results should be better. Currently supported only with ARCore NDK driver.</string>
<string name="pref_title_arcore_localization_filtering_speed">ARCore Localization Filtering Speed</string>
<string name="pref_summary_arcore_localization_filtering_speed">Filter ARCore\'s localizations to avoid jumps in odometry when creating a map with RTAB-Map, which would cause large drift errors that are difficult to correct. Set a speed threshold to detect those events.</string>
<string name="pref_title_append">Append Mode</string> <string name="pref_title_append">Append Mode</string>
<string name="pref_summary_append">When resuming mapping, wait for a relocalization on the current map before starting a new map.</string> <string name="pref_summary_append">When resuming mapping, wait for a relocalization on the current map before starting a new map.</string>
<string name="pref_title_resolution">HD Mode</string> <string name="pref_title_resolution">HD Mode</string>
@@ -344,15 +365,35 @@
<string name="pref_summary_optimizer">Graph optimization approach.</string> <string name="pref_summary_optimizer">Graph optimization approach.</string>
<string name="pref_title_optimize_end">Optimization from Graph End</string> <string name="pref_title_optimize_end">Optimization from Graph End</string>
<string name="pref_summary_optimize_end">The map\'s graph is optimized from the last node. The map is moved when a loop closure happens instead of jumping the current pose back to localized area. </string> <string name="pref_summary_optimize_end">The map\'s graph is optimized from the last node. The map is moved when a loop closure happens instead of jumping the current pose back to localized area. </string>
<string name="pref_title_marker_detection">ArUco Marker Detection</string>
<string name="pref_summary_marker_detection">ArUco markers can be detected for localization and graph optimization.</string>
<string name="pref_title_marker_detection_depth_error">Marker Depth Error Estimation</string>
<string name="pref_summary_marker_detection_depth_error">Size of markers are automatically initialized on the first marker seen. All markers should have the same size. This value is the maximum depth error to do the initialization to get accurate size of the tag. The lower it is, the more perpendicular the camera should be from the marker to do initialization, but size estimated would be more accurate.</string>
<string name="pref_title_keep_all_db">Save All Frames in Database</string> <string name="pref_title_keep_all_db">Save All Frames in Database</string>
<string name="pref_summary_keep_all_db">Discarded frames while not moving are still saved in database. Useful to replay exactly the scanning on RTAB-Map Desktop.</string> <string name="pref_summary_keep_all_db">Discarded frames while not moving are still saved in database. Useful to replay exactly the scanning on RTAB-Map Desktop.</string>
<string name="pref_title_raw_scan_saved">Save Raw Scan</string> <string name="pref_title_raw_scan_saved">Save Raw Scan</string>
<string name="pref_summary_raw_scan_saved">Save raw point clouds in database.</string> <string name="pref_summary_raw_scan_saved">Save raw point clouds in database.</string>
<string name="pref_title_gps_saved">Save GPS</string> <string name="pref_title_gps_saved">Save GPS</string>
<string name="pref_summary_gps_saved">Save GPS in database.</string> <string name="pref_summary_gps_saved">Save GPS to database.</string>
<string name="pref_title_db_in_memory">Database In Memory</string> <string name="pref_title_env_sensors_saved">Save Environmental Sensors</string>
<string name="pref_summary_env_sensors_saved">Save Wifi strength, temperature, air pressure, light intensity and relative humidity to database.</string>
<string name="pref_title_db_in_memory">Database in Memory</string>
<string name="pref_summary_db_in_memory">The database is kept in RAM for fast access. Set to false to reduce RAM used at the cost of slower access. This parameter is applied on reset or when a database is opened.</string> <string name="pref_summary_db_in_memory">The database is kept in RAM for fast access. Set to false to reduce RAM used at the cost of slower access. This parameter is applied on reset or when a database is opened.</string>
<string-array name="pref_camera_driver_keys">
<item>"Auto"</item>
<item>"Google Tango NDK"</item>
<item>"ARCore NDK"</item>
<item>"AREngine NDK"</item>
<item>"ARCore Java"</item>
</string-array>
<string-array name="pref_camera_driver_values">
<item>"-1"</item>
<item>"0"</item>
<item>"1"</item>
<item>"2"</item>
<item>"3"</item>
</string-array>
<string-array name="pref_update_rate_keys"> <string-array name="pref_update_rate_keys">
<item>"Max"</item> <item>"Max"</item>
<item>"5 Hz"</item> <item>"5 Hz"</item>
@@ -371,6 +412,24 @@
<item>"1"</item> <item>"1"</item>
<item>"0.5"</item> <item>"0.5"</item>
</string-array> </string-array>
<string-array name="pref_arcore_localization_filtering_speed_keys">
<item>"Disabled"</item>
<item>"5 m/s"</item>
<item>"4 m/s"</item>
<item>"3 m/s"</item>
<item>"2 m/s"</item>
<item>"1 m/s"</item>
<item>"0.5 m/s"</item>
</string-array>
<string-array name="pref_arcore_localization_filtering_speed_values">
<item>"0"</item>
<item>"5"</item>
<item>"4"</item>
<item>"3"</item>
<item>"2"</item>
<item>"1"</item>
<item>"0.5"</item>
</string-array>
<string-array name="pref_max_speed_keys"> <string-array name="pref_max_speed_keys">
<item>"No Limit"</item> <item>"No Limit"</item>
<item>"High"</item> <item>"High"</item>
@@ -398,7 +457,7 @@
<item>"700 ms"</item> <item>"700 ms"</item>
<item>"600 ms"</item> <item>"600 ms"</item>
<item>"500 ms"</item> <item>"500 ms"</item>
<item>"400"</item> <item>"400 ms"</item>
</string-array> </string-array>
<string-array name="pref_time_thr_values"> <string-array name="pref_time_thr_values">
<item>"0"</item> <item>"0"</item>
@@ -494,29 +553,25 @@
<item>"10"</item> <item>"10"</item>
</string-array> </string-array>
<string-array name="pref_opt_error_keys"> <string-array name="pref_opt_error_keys">
<item>"10x"</item>
<item>"9x"</item>
<item>"8x"</item>
<item>"7x"</item>
<item>"6x"</item>
<item>"5x"</item>
<item>"4x"</item> <item>"4x"</item>
<item>"3.5x"</item>
<item>"3x"</item> <item>"3x"</item>
<item>"2.5x"</item>
<item>"2x"</item> <item>"2x"</item>
<item>"1.5x"</item>
<item>"1x"</item> <item>"1x"</item>
<item>"0.5x"</item>
<item>"Disabled"</item> <item>"Disabled"</item>
</string-array> </string-array>
<string-array name="pref_opt_error_values"> <string-array name="pref_opt_error_values">
<item>"10"</item>
<item>"9"</item>
<item>"8"</item>
<item>"7"</item>
<item>"6"</item>
<item>"5"</item>
<item>"4"</item> <item>"4"</item>
<item>"3.5"</item>
<item>"3"</item> <item>"3"</item>
<item>"2.5"</item>
<item>"2"</item> <item>"2"</item>
<item>"1.5"</item>
<item>"1"</item> <item>"1"</item>
<item>"0.5"</item>
<item>"0"</item> <item>"0"</item>
</string-array> </string-array>
<string-array name="pref_features_voc_keys"> <string-array name="pref_features_voc_keys">
@@ -591,10 +646,95 @@
<item>"1"</item> <item>"1"</item>
<item>"0"</item> <item>"0"</item>
</string-array> </string-array>
<string-array name="pref_marker_detection_keys">
<item>"Disabled"</item>
<item>"4X4_50"</item>
<item>"4X4_100"</item>
<item>"4X4_250"</item>
<item>"4X4_1000"</item>
<item>"5X5_50"</item>
<item>"5X5_100"</item>
<item>"5X5_250"</item>
<item>"5X5_1000"</item>
<item>"6X6_50"</item>
<item>"6X6_100"</item>
<item>"6X6_250"</item>
<item>"6X6_1000"</item>
<item>"7X7_50"</item>
<item>"7X7_100"</item>
<item>"7X7_250"</item>
<item>"7X7_1000"</item>
<item>"ARUCO_ORIGINAL"</item>
<item>"APRILTAG_16h5"</item>
<item>"APRILTAG_25h9"</item>
<item>"APRILTAG_36h10"</item>
<item>"APRILTAG_36h11"</item>
</string-array>
<string-array name="pref_marker_detection_values">
<item>"-1"</item>
<item>"0"</item>
<item>"1"</item>
<item>"2"</item>
<item>"3"</item>
<item>"4"</item>
<item>"5"</item>
<item>"6"</item>
<item>"7"</item>
<item>"8"</item>
<item>"9"</item>
<item>"10"</item>
<item>"11"</item>
<item>"12"</item>
<item>"13"</item>
<item>"14"</item>
<item>"15"</item>
<item>"16"</item>
<item>"17"</item>
<item>"18"</item>
<item>"19"</item>
<item>"20"</item>
</string-array>
<string-array name="pref_marker_detection_depth_error_keys">
<item>"1 cm"</item>
<item>"2 cm"</item>
<item>"3 cm"</item>
<item>"4 cm"</item>
<item>"5 cm"</item>
<item>"6 cm"</item>
<item>"7 cm"</item>
<item>"8 cm"</item>
<item>"9 cm"</item>
<item>"10 cm"</item>
<item>"15 cm"</item>
<item>"20 cm"</item>
<item>"30 cm"</item>
<item>"40 cm"</item>
<item>"50 cm"</item>
<item>"100 cm"</item>
</string-array>
<string-array name="pref_marker_detection_depth_error_values">
<item>"0.01"</item>
<item>"0.02"</item>
<item>"0.03"</item>
<item>"0.04"</item>
<item>"0.05"</item>
<item>"0.06"</item>
<item>"0.07"</item>
<item>"0.08"</item>
<item>"0.09"</item>
<item>"0.1"</item>
<item>"0.15"</item>
<item>"0.20"</item>
<item>"0.30"</item>
<item>"0.40"</item>
<item>"0.50"</item>
<item>"1"</item>
</string-array>
<string name="pref_title_export_sub">Exporting&#8230;</string> <string name="pref_title_export_sub">Assembling&#8230;</string>
<string name="pref_title_export">Exporting</string> <string name="pref_title_export">Assembling</string>
<string name="pref_summary_export">Advanced parameters used when exporting the map.</string> <string name="pref_summary_export">Advanced parameters used when assembling the map.</string>
<string name="pref_title_cloud_voxel">Voxel Size</string> <string name="pref_title_cloud_voxel">Voxel Size</string>
<string name="pref_summary_cloud_voxel">If you don\'t need a very precise point cloud, you can set this to reduce the output point cloud size. This is also used for optimized mesh.</string> <string name="pref_summary_cloud_voxel">If you don\'t need a very precise point cloud, you can set this to reduce the output point cloud size. This is also used for optimized mesh.</string>
<string name="pref_title_texture_size">Texture Size</string> <string name="pref_title_texture_size">Texture Size</string>
@@ -607,8 +747,8 @@
<string name="pref_summary_max_texture_distance">Maximum distance from a camera for polygons to be textured by this camera.</string> <string name="pref_summary_max_texture_distance">Maximum distance from a camera for polygons to be textured by this camera.</string>
<string name="pref_title_min_texture_cluster_size">Min Texture Cluster Size</string> <string name="pref_title_min_texture_cluster_size">Min Texture Cluster Size</string>
<string name="pref_summary_min_texture_cluster_size">Minimum polygon cluster size to be textured by a camera. This helps to filter sparse textured polygons.</string> <string name="pref_summary_min_texture_cluster_size">Minimum polygon cluster size to be textured by a camera. This helps to filter sparse textured polygons.</string>
<string name="pref_title_block_render">Block Rendering Thread While Exporting</string> <string name="pref_title_block_render">Block Rendering Thread While Assembling</string>
<string name="pref_summary_block_render">This decreases exporting time, but freezes rendering while exporting. This also clears temporary the rendered clouds/meshes from memory during exporting, this can be useful to avoid out of memory errors.</string> <string name="pref_summary_block_render">This decreases assembling time, but freezes rendering while assembling. This also clears temporary the rendered clouds/meshes from memory during assembling, this can be useful to avoid out of memory errors.</string>
<string-array name="pref_cloud_voxel_keys"> <string-array name="pref_cloud_voxel_keys">
<item>"0.2 m"</item> <item>"0.2 m"</item>
@@ -714,7 +854,7 @@
<string name="pref_title_opt_depth">Reconstruction Depth</string> <string name="pref_title_opt_depth">Reconstruction Depth</string>
<string name="pref_summary_opt_depth">Lowering this parameter decreases reconstruction time, but geometry precision is lower. Minimum polygon size: map length / 2^depth). \"Auto\" means that depth is chosen so that polygon size is just under 3 cm.</string> <string name="pref_summary_opt_depth">Lowering this parameter decreases reconstruction time, but geometry precision is lower. Minimum polygon size: map length / 2^depth). \"Auto\" means that depth is chosen so that polygon size is just under 3 cm.</string>
<string name="pref_title_opt_color_radius">Color Radius</string> <string name="pref_title_opt_color_radius">Color Radius</string>
<string name="pref_summary_opt_color_radius">Radius used to transfer nearest color from the point cloud to reconstructed mesh. When exporting with texture, if Clean Mesh is also enabled, this will limit the number of polygons textured in holes.</string> <string name="pref_summary_opt_color_radius">Radius used to transfer nearest color from the point cloud to reconstructed mesh. When assembling with texture, if Clean Mesh is also enabled, this will limit the number of polygons textured in holes.</string>
<string name="pref_title_opt_clean_white">Clean Mesh</string> <string name="pref_title_opt_clean_white">Clean Mesh</string>
<string name="pref_summary_opt_clean_white">Clean mesh from textureless or colorless reconstructed polygons.</string> <string name="pref_summary_opt_clean_white">Clean mesh from textureless or colorless reconstructed polygons.</string>
<string name="pref_summary_opt_min_cluster_size">This can be used to filter polygons before texturing.</string> <string name="pref_summary_opt_min_cluster_size">This can be used to filter polygons before texturing.</string>
@@ -748,10 +888,10 @@
<item>"0.2 m"</item> <item>"0.2 m"</item>
<item>"0.1 m"</item> <item>"0.1 m"</item>
<item>"0.05 m"</item> <item>"0.05 m"</item>
<item>"0.025"</item> <item>"0.025 m"</item>
<item>"0.02"</item> <item>"0.02 m"</item>
<item>"0.015"</item> <item>"0.015 m"</item>
<item>"0.01"</item> <item>"0.01 m"</item>
<item>"Disabled"</item> <item>"Disabled"</item>
</string-array> </string-array>
<string-array name="pref_opt_color_radius_values"> <string-array name="pref_opt_color_radius_values">
+4
View File
@@ -0,0 +1,4 @@
<?xml version="1.0" encoding="utf-8"?>
<paths xmlns:android="http://schemas.android.com/apk/res/android">
<external-path name="external_files" path="."/>
</paths>
@@ -0,0 +1,882 @@
package com.introlab.rtabmap;
import java.nio.ByteBuffer;
import java.nio.FloatBuffer;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.EnumSet;
import java.util.List;
import java.util.concurrent.atomic.AtomicBoolean;
import com.google.ar.core.Anchor;
import com.google.ar.core.Camera;
import com.google.ar.core.CameraConfig;
import com.google.ar.core.CameraConfigFilter;
import com.google.ar.core.CameraIntrinsics;
import com.google.ar.core.Config;
import com.google.ar.core.Coordinates2d;
import com.google.ar.core.Frame;
import com.google.ar.core.PointCloud;
import com.google.ar.core.Pose;
import com.google.ar.core.Session;
import com.google.ar.core.SharedCamera;
import com.google.ar.core.TrackingState;
import com.google.ar.core.exceptions.CameraNotAvailableException;
import com.google.ar.core.exceptions.NotYetAvailableException;
import com.google.ar.core.exceptions.UnavailableException;
import android.content.Context;
import android.graphics.ImageFormat;
import android.hardware.camera2.CameraAccessException;
import android.hardware.camera2.CameraCaptureSession;
import android.hardware.camera2.CameraCharacteristics;
import android.hardware.camera2.CameraDevice;
import android.hardware.camera2.CameraManager;
import android.hardware.camera2.CameraMetadata;
import android.hardware.camera2.CaptureFailure;
import android.hardware.camera2.CaptureRequest;
import android.hardware.camera2.TotalCaptureResult;
import android.media.Image;
import android.opengl.GLES20;
import android.opengl.GLSurfaceView;
import android.os.Handler;
import android.os.HandlerThread;
import android.support.annotation.NonNull;
import android.util.Log;
import android.view.Surface;
import android.widget.Toast;
public class ARCoreSharedCamera {
public static final String TAG = ARCoreSharedCamera.class.getSimpleName();
private static final float[] QUAD_COORDS =
new float[] {
-1.0f, -1.0f, +1.0f, -1.0f, -1.0f, +1.0f, +1.0f, +1.0f,
};
private static RTABMapActivity mActivity;
public ARCoreSharedCamera(RTABMapActivity c, float arCoreLocalizationFilteringSpeed) {
mActivity = c;
mARCoreLocalizationFilteringSpeed = arCoreLocalizationFilteringSpeed;
}
// Depth TOF Image.
// Use 240 * 180 for now, hardcoded for Huawei P30 Pro
private int depthWidth = 640;
private int depthHeight = 480;
// GL Surface used to draw camera preview image.
public GLSurfaceView surfaceView;
// ARCore session that supports camera sharing.
private Session sharedSession;
private Pose previousAnchorPose = null;
private long previousAnchorTimeStamp;
private Pose arCoreCorrection = Pose.IDENTITY;
private Pose odomPose = Pose.IDENTITY;
private float mARCoreLocalizationFilteringSpeed = 1.0f;
// Camera capture session. Used by both non-AR and AR modes.
private CameraCaptureSession captureSession;
// Reference to the camera system service.
private CameraManager cameraManager;
// Camera device. Used by both non-AR and AR modes.
private CameraDevice cameraDevice;
// Looper handler thread.
private HandlerThread backgroundThread;
// Looper handler.
private Handler backgroundHandler;
// ARCore shared camera instance, obtained from ARCore session that supports sharing.
private SharedCamera sharedCamera;
private Toast mToast = null;
// Camera ID for the camera used by ARCore.
private String cameraId;
private String depthCameraId;
private Pose rgbExtrinsics;
private Pose depthExtrinsics;
private float[] depthIntrinsics = null;
private AtomicBoolean mReady = new AtomicBoolean(false);
// Camera preview capture request builder
private CaptureRequest.Builder previewCaptureRequestBuilder;
private int cameraTextureId = -1;
// Image reader that continuously processes CPU images.
public TOF_ImageReader mTOFImageReader = new TOF_ImageReader();
private boolean mTOFAvailable = false;
public boolean isDepthSupported() {return mTOFAvailable;}
public void setToast(Toast toast)
{
mToast = toast;
}
// Camera device state callback.
private final CameraDevice.StateCallback cameraDeviceCallback =
new CameraDevice.StateCallback() {
@Override
public void onOpened(@NonNull CameraDevice cameraDevice) {
Log.d(TAG, "Camera device ID " + cameraDevice.getId() + " opened.");
ARCoreSharedCamera.this.cameraDevice = cameraDevice;
createCameraPreviewSession();
}
@Override
public void onClosed(@NonNull CameraDevice cameraDevice) {
Log.d(TAG, "Camera device ID " + cameraDevice.getId() + " closed.");
ARCoreSharedCamera.this.cameraDevice = null;
}
@Override
public void onDisconnected(@NonNull CameraDevice cameraDevice) {
Log.w(TAG, "Camera device ID " + cameraDevice.getId() + " disconnected.");
cameraDevice.close();
ARCoreSharedCamera.this.cameraDevice = null;
}
@Override
public void onError(@NonNull CameraDevice cameraDevice, int error) {
Log.e(TAG, "Camera device ID " + cameraDevice.getId() + " error " + error);
cameraDevice.close();
ARCoreSharedCamera.this.cameraDevice = null;
}
};
// Repeating camera capture session state callback.
CameraCaptureSession.StateCallback cameraCaptureCallback =
new CameraCaptureSession.StateCallback() {
// Called when the camera capture session is first configured after the app
// is initialized, and again each time the activity is resumed.
@Override
public void onConfigured(@NonNull CameraCaptureSession session) {
Log.d(TAG, "Camera capture session configured.");
captureSession = session;
setRepeatingCaptureRequest();
}
@Override
public void onSurfacePrepared(
@NonNull CameraCaptureSession session, @NonNull Surface surface) {
Log.d(TAG, "Camera capture surface prepared.");
}
@Override
public void onReady(@NonNull CameraCaptureSession session) {
Log.d(TAG, "Camera capture session ready.");
}
@Override
public void onActive(@NonNull CameraCaptureSession session) {
Log.d(TAG, "Camera capture session active.");
resumeARCore();
}
@Override
public void onClosed(@NonNull CameraCaptureSession session) {
Log.d(TAG, "Camera capture session closed.");
}
@Override
public void onConfigureFailed(@NonNull CameraCaptureSession session) {
Log.e(TAG, "Failed to configure camera capture session.");
}
};
// Repeating camera capture session capture callback.
private final CameraCaptureSession.CaptureCallback captureSessionCallback =
new CameraCaptureSession.CaptureCallback() {
@Override
public void onCaptureCompleted(
@NonNull CameraCaptureSession session,
@NonNull CaptureRequest request,
@NonNull TotalCaptureResult result) {
//Log.i(TAG, "onCaptureCompleted");
}
//@Override // android 23
public void onCaptureBufferLost(
@NonNull CameraCaptureSession session,
@NonNull CaptureRequest request,
@NonNull Surface target,
long frameNumber) {
Log.e(TAG, "onCaptureBufferLost: " + frameNumber);
}
@Override
public void onCaptureFailed(
@NonNull CameraCaptureSession session,
@NonNull CaptureRequest request,
@NonNull CaptureFailure failure) {
Log.e(TAG, "onCaptureFailed: " + failure.getFrameNumber() + " " + failure.getReason());
}
@Override
public void onCaptureSequenceAborted(
@NonNull CameraCaptureSession session, int sequenceId) {
Log.e(TAG, "onCaptureSequenceAborted: " + sequenceId + " " + session);
}
};
private void resumeARCore() {
// Ensure that session is valid before triggering ARCore resume. Handles the case where the user
// manually uninstalls ARCore while the app is paused and then resumes.
if (sharedSession == null) {
return;
}
try {
Log.i(TAG, "Resume ARCore.");
// Resume ARCore.
sharedSession.resume();
// Set capture session callback while in AR mode.
sharedCamera.setCaptureCallback(captureSessionCallback, backgroundHandler);
} catch (CameraNotAvailableException e) {
Log.e(TAG, "Failed to resume ARCore session", e);
return;
}
}
// Called when starting non-AR mode or switching to non-AR mode.
// Also called when app starts in AR mode, or resumes in AR mode.
private void setRepeatingCaptureRequest() {
try {
captureSession.setRepeatingRequest(
previewCaptureRequestBuilder.build(), captureSessionCallback, backgroundHandler);
} catch (CameraAccessException e) {
Log.e(TAG, "Failed to set repeating request", e);
}
}
private void createCameraPreviewSession() {
Log.e(TAG, "createCameraPreviewSession: " + "starting camera preview session.");
try {
// Note that isGlAttached will be set to true in AR mode in onDrawFrame().
sharedSession.setCameraTextureName(cameraTextureId);
// Create an ARCore compatible capture request using `TEMPLATE_RECORD`.
previewCaptureRequestBuilder = cameraDevice.createCaptureRequest(CameraDevice.TEMPLATE_RECORD);
// Build surfaces list, starting with ARCore provided surfaces.
List<Surface> surfaceList = sharedCamera.getArCoreSurfaces();
Log.e(TAG, " createCameraPreviewSession: " + "surfaceList: sharedCamera.getArCoreSurfaces(): " + surfaceList.size());
// Add a CPU image reader surface. On devices that don't support CPU image access, the image
// may arrive significantly later, or not arrive at all.
if (mTOFAvailable && cameraId.compareTo(depthCameraId) == 0) surfaceList.add(mTOFImageReader.imageReader.getSurface());
// Surface list should now contain three surfacemReadymReadys:
// 0. sharedCamera.getSurfaceTexture()
// 1. …
// 2. depthImageReader.getSurface()
// Add ARCore surfaces and CPU image surface targets.
for (Surface surface : surfaceList) {
previewCaptureRequestBuilder.addTarget(surface);
}
// Wrap our callback in a shared camera callback.
CameraCaptureSession.StateCallback wrappedCallback = sharedCamera.createARSessionStateCallback(cameraCaptureCallback, backgroundHandler);
// Create camera capture session for camera preview using ARCore wrapped callback.
cameraDevice.createCaptureSession(surfaceList, wrappedCallback, backgroundHandler);
mReady.set(true);
} catch (CameraAccessException e) {
Log.e(TAG, "CameraAccessException", e);
}
}
// Start background handler thread, used to run callbacks without blocking UI thread.
private void startBackgroundThread() {
backgroundThread = new HandlerThread("sharedCameraBackground");
backgroundThread.start();
backgroundHandler = new Handler(backgroundThread.getLooper());
mTOFImageReader.startBackgroundThread();
}
// Stop background handler thread.
private void stopBackgroundThread() {
if (backgroundThread != null) {
backgroundThread.quitSafely();
try {
backgroundThread.join();
backgroundThread = null;
backgroundHandler = null;
} catch (InterruptedException e) {
Log.e(TAG, "Interrupted while trying to join background handler thread", e);
}
}
mTOFImageReader.stopBackgroundThread();
}
/**
* Return true if the given array contains the given integer.
*
* @param modes array to check.
* @param mode integer to get for.
* @return true if the array contains the given integer, otherwise false.
*/
private static boolean contains(int[] modes, int mode) {
if (modes == null) {
return false;
}
for (int i : modes) {
if (i == mode) {
return true;
}
}
return false;
}
// Perform various checks, then open camera device and create CPU image reader.
public boolean openCamera() {
close();
startBackgroundThread();
if(cameraTextureId == -1)
{
int[] textures = new int[1];
GLES20.glGenTextures(1, textures, 0);
cameraTextureId = textures[0];
}
Log.v(TAG, "Perform various checks, then open camera device and create CPU image reader.");
// Don't open camera if already opened.
if (cameraDevice != null) {
return false;
}
if (sharedSession == null) {
try {
// Create ARCore session that supports camera sharing.
sharedSession = new Session(mActivity, EnumSet.of(Session.Feature.SHARED_CAMERA));
} catch (UnavailableException e) {
Log.e(TAG, "Failed to create ARCore session that supports camera sharing", e);
return false;
}
// First obtain the session handle before getting the list of various camera configs.
// Create filter here with desired fps filters.
CameraConfigFilter cameraConfigFilter = new CameraConfigFilter(sharedSession);
CameraConfig[] cameraConfigs = sharedSession.getSupportedCameraConfigs(cameraConfigFilter).toArray(new CameraConfig[0]);
Log.i(TAG, "Size of supported CameraConfigs list is " + cameraConfigs.length);
// Determine the highest and lowest CPU resolutions.
int highestResolutionIndex=-1;
int highestResolution = 0;
for(int i=0; i<cameraConfigs.length; ++i)
{
Log.i(TAG, "Camera ID: " + cameraConfigs[i].getCameraId());
Log.i(TAG, "Resolution: " + cameraConfigs[i].getImageSize().getWidth() + "x" + cameraConfigs[i].getImageSize().getHeight());
if(highestResolution == 0 || highestResolution < cameraConfigs[i].getImageSize().getWidth())
{
highestResolutionIndex = i;
highestResolution = cameraConfigs[i].getImageSize().getWidth();
}
}
if(highestResolutionIndex>=0)
{
//Log.i(TAG, "Setting camera resolution to " + cameraConfigs[highestResolutionIndex].getImageSize().getWidth() + "x" + cameraConfigs[highestResolutionIndex].getImageSize().getHeight());
//FIXME: Can we make it work to use HD rgb images? To avoid this error "CaptureRequest contains unconfigured Input/Output Surface!"
//sharedSession.setCameraConfig(cameraConfigs[highestResolutionIndex]);
}
// Enable auto focus mode while ARCore is running.
Config config = sharedSession.getConfig();
config.setFocusMode(Config.FocusMode.FIXED);
config.setUpdateMode(Config.UpdateMode.BLOCKING);
config.setPlaneFindingMode(Config.PlaneFindingMode.DISABLED);
config.setLightEstimationMode(Config.LightEstimationMode.DISABLED);
config.setCloudAnchorMode(Config.CloudAnchorMode.DISABLED);
sharedSession.configure(config);
}
// Store the ARCore shared camera reference.
sharedCamera = sharedSession.getSharedCamera();
// Store the ID of the camera used by ARCore.
cameraId = sharedSession.getCameraConfig().getCameraId();
Log.d(TAG, "Shared camera ID: " + cameraId);
mTOFAvailable = false;
// Store a reference to the camera system service.
cameraManager = (CameraManager) mActivity.getSystemService(Context.CAMERA_SERVICE);
depthCameraId = null;
// show all cameras
try {
// Find a CameraDevice that supports DEPTH16 captures, and configure state.
for (String tmpCameraId : cameraManager.getCameraIdList()) {
CameraCharacteristics characteristics = cameraManager.getCameraCharacteristics(tmpCameraId);
Log.i(TAG, "Camera " + tmpCameraId + " extrinsics:");
float[] translation = characteristics.get(CameraCharacteristics.LENS_POSE_TRANSLATION);
if(translation != null)
{
Log.i(TAG, String.format("Translation (x,y,z): %f,%f,%f", translation[0], translation[1], translation[2]));
}
float[] rotation = characteristics.get(CameraCharacteristics.LENS_POSE_ROTATION);
if(rotation != null)
{
Log.i(TAG, String.format("Rotation (qx,qy,qz,qw): %f,%f,%f,%f", rotation[0], rotation[1], rotation[2], rotation[3]));
}
if(tmpCameraId.compareTo(cameraId)==0 && translation!=null && rotation!=null)
{
rgbExtrinsics = new Pose(translation, rotation);
Log.i(TAG,"Set rgb extrinsics!");
}
if (!contains(characteristics.get(CameraCharacteristics.REQUEST_AVAILABLE_CAPABILITIES), CameraCharacteristics.REQUEST_AVAILABLE_CAPABILITIES_DEPTH_OUTPUT) ||
characteristics.get(CameraCharacteristics.LENS_FACING) == CameraMetadata.LENS_FACING_FRONT) {
continue;
}
Log.i(TAG, "Camera " + tmpCameraId + " has depth output available");
depthCameraId = tmpCameraId;
if(translation!=null && rotation != null)
{
depthExtrinsics = new Pose(translation, rotation);
Log.i(TAG,"Set depth extrinsics!");
}
depthIntrinsics = characteristics.get(CameraCharacteristics.LENS_INTRINSIC_CALIBRATION);
Log.i(TAG, String.format("Intrinsics (fx,fy,cx,cy,s): %f,%f,%f,%f,%f",
depthIntrinsics[0],
depthIntrinsics[1],
depthIntrinsics[2],
depthIntrinsics[3],
depthIntrinsics[4]));
}
} catch (CameraAccessException e) {
e.printStackTrace();
}
if(rgbExtrinsics == null)
{
float[] translation = {0,0,0};
float[] rotation = {0,0,0,1};
rgbExtrinsics = new Pose(translation, rotation);
}
if(depthExtrinsics == null)
{
depthExtrinsics = rgbExtrinsics;
}
if(depthCameraId != null)
{
ArrayList<String> resolutions = getResolutions(mActivity, depthCameraId, ImageFormat.DEPTH16);
if (resolutions != null) {
float[] newDepthIntrinsics = null;
int largestWidth = 0;
for( String temp : resolutions) {
Log.i(TAG, "DEPTH16 resolution: " + temp);
depthWidth = Integer.parseInt(temp.split("x")[0]);
depthHeight = Integer.parseInt(temp.split("x")[1]);
if(depthIntrinsics != null)
{
if(depthIntrinsics[0] != 0)
{
if(largestWidth == 0 && depthWidth>largestWidth)
{
largestWidth = depthWidth; // intrinsics should match this resolution
}
// Samsung Galaxy Note10+: take smallest resolution and match the intrinsics
if(depthWidth < largestWidth)
{
float scale = (float)depthWidth/(float)largestWidth;
newDepthIntrinsics = depthIntrinsics.clone();
newDepthIntrinsics[0] *= scale;
newDepthIntrinsics[1] *= scale;
newDepthIntrinsics[2] *= scale;
newDepthIntrinsics[3] *= scale;
}
}
else if(depthWidth ==240 && depthHeight==180)
{
// Huawei P30 Pro: only 240x180 is working
break;
}
}
}
if (resolutions.size()>0) {
mTOFAvailable = true;
if(newDepthIntrinsics!=null) {
depthIntrinsics = newDepthIntrinsics;
}
}
}
}
Log.i(TAG, "TOF_available: " + mTOFAvailable);
// Color CPU Image.
// Use the currently configured CPU image size.
//Size desiredCPUImageSize = sharedSession.getCameraConfig().getImageSize();
if (mTOFAvailable) mTOFImageReader.createImageReader(depthWidth, depthHeight);
// When ARCore is running, make sure it also updates our CPU image surface.
if (mTOFAvailable && cameraId.compareTo(depthCameraId) == 0) {
sharedCamera.setAppSurfaces(this.cameraId, Arrays.asList(mTOFImageReader.imageReader.getSurface()));
}
try {
// Wrap our callback in a shared camera callback.
CameraDevice.StateCallback wrappedCallback = sharedCamera.createARDeviceStateCallback(cameraDeviceCallback, backgroundHandler);
// Open the camera device using the ARCore wrapped callback.
cameraManager.openCamera(cameraId, wrappedCallback, backgroundHandler);
if(mTOFAvailable && cameraId.compareTo(depthCameraId) != 0)
{
cameraManager.openCamera(depthCameraId, mTOFImageReader.cameraDeviceCallback, mTOFImageReader.backgroundHandler);
}
} catch (CameraAccessException e) {
Log.e(TAG, "Failed to open camera", e);
return false;
} catch (IllegalArgumentException e) {
Log.e(TAG, "Failed to open camera", e);
return false;
} catch (SecurityException e) {
Log.e(TAG, "Failed to open camera", e);
return false;
}
return true;
}
public static void rotationMatrixToQuaternion(float[] R, float[] q) {
final float m00 = R[0];
final float m10 = R[1];
final float m20 = R[2];
final float m01 = R[4];
final float m11 = R[5];
final float m21 = R[6];
final float m02 = R[8];
final float m12 = R[9];
final float m22 = R[10];
float tr = m00 + m11 + m22;
if (tr > 0) {
float S = (float) Math.sqrt(tr + 1.0) * 2; // S=4*qw
q[0] = 0.25f * S;/* w w w.j ava 2s.co m*/
q[1] = (m21 - m12) / S;
q[2] = (m02 - m20) / S;
q[3] = (m10 - m01) / S;
} else if ((m00 > m11) & (m00 > m22)) {
float S = (float) Math.sqrt(1.0 + m00 - m11 - m22) * 2; //
// S=4*q[1]
q[0] = (m21 - m12) / S;
q[1] = 0.25f * S;
q[2] = (m01 + m10) / S;
q[3] = (m02 + m20) / S;
} else if (m11 > m22) {
float S = (float) Math.sqrt(1.0 + m11 - m00 - m22) * 2; //
// S=4*q[2]
q[0] = (m02 - m20) / S;
q[1] = (m01 + m10) / S;
q[2] = 0.25f * S;
q[3] = (m12 + m21) / S;
} else {
float S = (float) Math.sqrt(1.0 + m22 - m00 - m11) * 2; //
// S=4*q[3]
q[0] = (m10 - m01) / S;
q[1] = (m02 + m20) / S;
q[2] = (m12 + m21) / S;
q[3] = 0.25f * S;
}
}
// Close the camera device.
public void close() {
Log.w(TAG, "close()");
if (sharedSession != null) {
sharedSession.close();
sharedSession = null;
}
if (captureSession != null) {
captureSession.close();
captureSession = null;
}
if (cameraDevice != null) {
cameraDevice.close();
cameraDevice = null;
}
mTOFImageReader.close();
if(cameraTextureId>=0)
{
GLES20.glDeleteTextures(1, new int[] {cameraTextureId}, 0);
}
stopBackgroundThread();
}
public void setDisplayGeometry(int rotation, int width, int height)
{
if(sharedSession!=null)
sharedSession.setDisplayGeometry(rotation, width, height);
}
/*************************************************** ONDRAWFRAME ARCORE ************************************************************* */
// Draw frame when in AR mode. Called on the GL thread.
public void updateGL() throws CameraNotAvailableException {
if(!mReady.get() || sharedSession == null)
{
return;
}
if (mTOFAvailable && mTOFImageReader.frameCount == 0) return;
// Perform ARCore per-frame update.
Frame frame = null;
try {
frame = sharedSession.update();
} catch (Exception e) {
e.printStackTrace();
return;
}
Camera camera = null;
if (frame != null) {
camera = frame.getCamera();
}else
{
Log.e(TAG, String.format("frame.getCamera() null!"));
return;
}
if (camera == null) {
Log.e(TAG, String.format("camera is null!"));
return;
}
if (camera.getTrackingState() != TrackingState.TRACKING) {
final String trackingState = camera.getTrackingState().toString();
Log.e(TAG, String.format("Tracking lost! state=%s", trackingState));
// This will force a new session on the next frame received
RTABMapLib.postCameraPoseEvent(RTABMapActivity.nativeApplication, 0,0,0,0,0,0,0,0);
mActivity.runOnUiThread(new Runnable() {
public void run() {
if(mToast!=null && previousAnchorPose != null)
{
String msg = "Tracking lost! If you are mapping, you will need to relocalize before continuing.";
if(mToast.getView() == null || !mToast.getView().isShown())
{
mToast.makeText(mActivity.getApplicationContext(),
msg, Toast.LENGTH_LONG).show();
}
else
{
mToast.setText(msg);
}
previousAnchorPose = null;
}
}
});
return;
}
if (frame.getTimestamp() != 0) {
Pose pose = camera.getPose();
// Remove ARCore SLAM corrections by integrating pose from previous frame anchor
if(previousAnchorPose == null || mARCoreLocalizationFilteringSpeed==0)
{
odomPose = pose;
}
else
{
float[] t = previousAnchorPose.inverse().compose(pose).getTranslation();
final double speed = Math.sqrt(t[0]*t[0]+t[1]*t[1]+t[2]*t[2])/((double)(frame.getTimestamp()-previousAnchorTimeStamp)/10e8);
if(speed>=mARCoreLocalizationFilteringSpeed)
{
arCoreCorrection = arCoreCorrection.compose(previousAnchorPose).compose(pose.inverse());
t = arCoreCorrection.getTranslation();
Log.e(TAG, String.format("POTENTIAL TELEPORTATION!!!!!!!!!!!!!! previous anchor moved (speed=%f), new arcorrection: %f %f %f", speed, t[0], t[1], t[2]));
t = odomPose.getTranslation();
float[] t2 = (arCoreCorrection.compose(pose)).getTranslation();
float[] t3 = previousAnchorPose.getTranslation();
float[] t4 = pose.getTranslation();
Log.e(TAG, String.format("Odom = %f %f %f -> %f %f %f ArCore= %f %f %f -> %f %f %f", t[0], t[1], t[2], t2[0], t2[1], t2[2], t3[0], t3[1], t3[2], t4[0], t4[1], t4[2]));
mActivity.runOnUiThread(new Runnable() {
public void run() {
if(mToast!=null)
{
String msg = String.format("ARCore localization has been suppressed "
+ "because of high speed detected (%f m/s) causing a jump! You can change "
+ "ARCore localization filtering speed in Settings->Mapping if you are "
+ "indeed moving as fast.", speed);
if(mToast.getView() == null || !mToast.getView().isShown())
{
mToast.makeText(mActivity.getApplicationContext(), msg, Toast.LENGTH_LONG).show();
}
else
{
mToast.setText(msg);
}
previousAnchorPose = null;
}
}
});
}
odomPose = arCoreCorrection.compose(pose);
}
previousAnchorPose = pose;
previousAnchorTimeStamp = frame.getTimestamp();
double stamp = (double)frame.getTimestamp()/10e8;
if(!RTABMapActivity.DISABLE_LOG) Log.d(TAG, String.format("pose=%f %f %f q=%f %f %f %f stamp=%f", odomPose.tx(), odomPose.ty(), odomPose.tz(), odomPose.qx(), odomPose.qy(), odomPose.qz(), odomPose.qw(), stamp));
RTABMapLib.postCameraPoseEvent(RTABMapActivity.nativeApplication, odomPose.tx(), odomPose.ty(), odomPose.tz(), odomPose.qx(), odomPose.qy(), odomPose.qz(), odomPose.qw(), stamp);
CameraIntrinsics intrinsics = camera.getImageIntrinsics();
try{
Image image = frame.acquireCameraImage();
if(!RTABMapActivity.DISABLE_LOG) Log.d(TAG, String.format("frame=%d vs image=%d", frame.getTimestamp(), image.getTimestamp()));
PointCloud cloud = frame.acquirePointCloud();
FloatBuffer points = cloud.getPoints();
if (image.getFormat() != ImageFormat.YUV_420_888) {
throw new IllegalArgumentException(
"Expected image in YUV_420_888 format, got format " + image.getFormat());
}
if(!RTABMapActivity.DISABLE_LOG)
{
for(int i =0;i<image.getPlanes().length;++i)
{
Log.d(TAG, String.format("Plane[%d] pixel stride = %d, row stride = %d", i, image.getPlanes()[i].getPixelStride(), image.getPlanes()[i].getRowStride()));
}
}
float[] fl = intrinsics.getFocalLength();
float[] pp = intrinsics.getPrincipalPoint();
if(!RTABMapActivity.DISABLE_LOG) Log.d(TAG, String.format("fx=%f fy=%f cx=%f cy=%f", fl[0], fl[1], pp[0], pp[1]));
ByteBuffer y = image.getPlanes()[0].getBuffer().asReadOnlyBuffer();
ByteBuffer u = image.getPlanes()[1].getBuffer().asReadOnlyBuffer();
ByteBuffer v = image.getPlanes()[2].getBuffer().asReadOnlyBuffer();
if(!RTABMapActivity.DISABLE_LOG) Log.d(TAG, String.format("RGB %dx%d len=%dbytes format=%d stamp=%f",
image.getWidth(), image.getHeight(), y.limit(), image.getFormat(), stamp));
float[] texCoord = new float[8];
frame.transformCoordinates2d(
Coordinates2d.OPENGL_NORMALIZED_DEVICE_COORDINATES,
QUAD_COORDS,
Coordinates2d.IMAGE_NORMALIZED,
texCoord);
float[] p = new float[16];
camera.getProjectionMatrix(p, 0, 0.1f, 100.0f);
float[] viewMatrix = new float[16];
arCoreCorrection.compose(camera.getDisplayOrientedPose()).inverse().toMatrix(viewMatrix, 0);
float[] quat = new float[4];
rotationMatrixToQuaternion(viewMatrix, quat);
if(mTOFAvailable)
{
ByteBuffer depth;
double depthStamp;
synchronized (mTOFImageReader) {
depth = mTOFImageReader.depth16_raw;
depthStamp = (double)mTOFImageReader.timestamp/10e8;
}
if(!RTABMapActivity.DISABLE_LOG) Log.d(TAG, String.format("Depth %dx%d len=%dbytes format=%d stamp=%f",
mTOFImageReader.WIDTH, mTOFImageReader.HEIGHT, depth.limit(), ImageFormat.DEPTH16, depthStamp));
RTABMapLib.postOdometryEventDepth(
RTABMapActivity.nativeApplication,
odomPose.tx(), odomPose.ty(), odomPose.tz(), odomPose.qx(), odomPose.qy(), odomPose.qz(), odomPose.qw(),
fl[0], fl[1], pp[0], pp[1],
depthIntrinsics[0], depthIntrinsics[1], depthIntrinsics[2], depthIntrinsics[3],
rgbExtrinsics.tx(), rgbExtrinsics.ty(), rgbExtrinsics.tz(), rgbExtrinsics.qx(), rgbExtrinsics.qy(), rgbExtrinsics.qz(), rgbExtrinsics.qw(),
depthExtrinsics.tx(), depthExtrinsics.ty(), depthExtrinsics.tz(), depthExtrinsics.qx(), depthExtrinsics.qy(), depthExtrinsics.qz(), depthExtrinsics.qw(),
stamp,
depthStamp,
y, u, v, y.limit(), image.getWidth(), image.getHeight(), image.getFormat(),
depth, depth.limit(), mTOFImageReader.WIDTH, mTOFImageReader.HEIGHT, ImageFormat.DEPTH16,
points, points.limit()/4,
viewMatrix[12], viewMatrix[13], viewMatrix[14], quat[1], quat[2], quat[3], quat[0],
p[0], p[5], p[8], p[9], p[10], p[11], p[14],
texCoord[0],texCoord[1],texCoord[2],texCoord[3],texCoord[4],texCoord[5],texCoord[6],texCoord[7]);
}
else
{
RTABMapLib.postOdometryEvent(
RTABMapActivity.nativeApplication,
odomPose.tx(), odomPose.ty(), odomPose.tz(), odomPose.qx(), odomPose.qy(), odomPose.qz(), odomPose.qw(),
fl[0], fl[1], pp[0], pp[1],
rgbExtrinsics.tx(), rgbExtrinsics.ty(), rgbExtrinsics.tz(), rgbExtrinsics.qx(), rgbExtrinsics.qy(), rgbExtrinsics.qz(), rgbExtrinsics.qw(),
stamp,
y, u, v, y.limit(), image.getWidth(), image.getHeight(), image.getFormat(),
points, points.limit()/4,
viewMatrix[12], viewMatrix[13], viewMatrix[14], quat[1], quat[2], quat[3], quat[0],
p[0], p[5], p[8], p[9], p[10], p[11], p[14],
texCoord[0],texCoord[1],texCoord[2],texCoord[3],texCoord[4],texCoord[5],texCoord[6],texCoord[7]);
}
image.close();
cloud.close();
} catch (NotYetAvailableException e) {
}
}
}
/********************************************************************************************************************* */
/*************************************************** End ************************************************************* */
/********************************************************************************************************************* */
public ArrayList<String> getResolutions (Context context, String cameraId, int imageFormat){
Log.v(TAG, "getResolutions: cameraId:" + cameraId + " imageFormat: " + imageFormat);
ArrayList<String> output = new ArrayList<String>();
try {
CameraManager manager = (CameraManager) context.getSystemService(Context.CAMERA_SERVICE);
CameraCharacteristics characteristics = manager.getCameraCharacteristics(cameraId);
for (android.util.Size s : characteristics.get(CameraCharacteristics.SCALER_STREAM_CONFIGURATION_MAP).getOutputSizes(imageFormat)) {
output.add(s.getWidth() + "x" + s.getHeight());
}
} catch (Exception e) {
e.printStackTrace();
}
return output;
}
}
@@ -0,0 +1,166 @@
package com.introlab.rtabmap;
/*
* Copyright 2017 Google LLC
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import android.app.Activity;
import android.content.Context;
import android.hardware.camera2.CameraAccessException;
import android.hardware.camera2.CameraCharacteristics;
import android.hardware.camera2.CameraManager;
import android.hardware.display.DisplayManager;
import android.hardware.display.DisplayManager.DisplayListener;
import android.view.Display;
import android.view.Surface;
import android.view.WindowManager;
import com.google.ar.core.Session;
/**
* Helper to track the display rotations. In particular, the 180 degree rotations are not notified
* by the onSurfaceChanged() callback, and thus they require listening to the android display
* events.
*/
public final class DisplayRotationHelper implements DisplayListener {
private boolean viewportChanged;
private int viewportWidth;
private int viewportHeight;
private final Display display;
private final DisplayManager displayManager;
private final CameraManager cameraManager;
/**
* Constructs the DisplayRotationHelper but does not register the listener yet.
*
* @param context the Android {@link Context}.
*/
public DisplayRotationHelper(Context context) {
displayManager = (DisplayManager) context.getSystemService(Context.DISPLAY_SERVICE);
cameraManager = (CameraManager) context.getSystemService(Context.CAMERA_SERVICE);
WindowManager windowManager = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);
display = windowManager.getDefaultDisplay();
}
/** Registers the display listener. Should be called from {@link Activity#onResume()}. */
public void onResume() {
displayManager.registerDisplayListener(this, null);
}
/** Unregisters the display listener. Should be called from {@link Activity#onPause()}. */
public void onPause() {
displayManager.unregisterDisplayListener(this);
}
/**
* Records a change in surface dimensions. This will be later used by {@link
* #updateSessionIfNeeded(Session)}. Should be called from {@link
* android.opengl.GLSurfaceView.Renderer
* #onSurfaceChanged(javax.microedition.khronos.opengles.GL10, int, int)}.
*
* @param width the updated width of the surface.
* @param height the updated height of the surface.
*/
public void onSurfaceChanged(int width, int height) {
viewportWidth = width;
viewportHeight = height;
viewportChanged = true;
}
/**
* Updates the session display geometry if a change was posted either by {@link
* #onSurfaceChanged(int, int)} call or by {@link #onDisplayChanged(int)} system callback. This
* function should be called explicitly before each call to {@link Session#update()}. This
* function will also clear the 'pending update' (viewportChanged) flag.
*
* @param session the {@link Session} object to update if display geometry changed.
*/
public void updateSessionIfNeeded(ARCoreSharedCamera session) {
if (viewportChanged) {
int displayRotation = display.getRotation();
session.setDisplayGeometry(displayRotation, viewportWidth, viewportHeight);
viewportChanged = false;
}
}
/**
* Returns the aspect ratio of the GL surface viewport while accounting for the display rotation
* relative to the device camera sensor orientation.
*/
public float getCameraSensorRelativeViewportAspectRatio(String cameraId) {
float aspectRatio;
int cameraSensorToDisplayRotation = getCameraSensorToDisplayRotation(cameraId);
switch (cameraSensorToDisplayRotation) {
case 90:
case 270:
aspectRatio = (float) viewportHeight / (float) viewportWidth;
break;
case 0:
case 180:
aspectRatio = (float) viewportWidth / (float) viewportHeight;
break;
default:
throw new RuntimeException("Unhandled rotation: " + cameraSensorToDisplayRotation);
}
return aspectRatio;
}
/**
* Returns the rotation of the back-facing camera with respect to the display. The value is one of
* 0, 90, 180, 270.
*/
public int getCameraSensorToDisplayRotation(String cameraId) {
CameraCharacteristics characteristics;
try {
characteristics = cameraManager.getCameraCharacteristics(cameraId);
} catch (CameraAccessException e) {
throw new RuntimeException("Unable to determine display orientation", e);
}
// Camera sensor orientation.
int sensorOrientation = characteristics.get(CameraCharacteristics.SENSOR_ORIENTATION);
// Current display orientation.
int displayOrientation = toDegrees(display.getRotation());
// Make sure we return 0, 90, 180, or 270 degrees.
return (sensorOrientation - displayOrientation + 360) % 360;
}
private int toDegrees(int rotation) {
switch (rotation) {
case Surface.ROTATION_0:
return 0;
case Surface.ROTATION_90:
return 90;
case Surface.ROTATION_180:
return 180;
case Surface.ROTATION_270:
return 270;
default:
throw new RuntimeException("Unknown rotation " + rotation);
}
}
@Override
public void onDisplayAdded(int displayId) {}
@Override
public void onDisplayRemoved(int displayId) {}
@Override
public void onDisplayChanged(int displayId) {
viewportChanged = true;
}
}
@@ -0,0 +1,79 @@
/*
* Copyright 2018 Google Inc. All Rights Reserved.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.introlab.rtabmap;
import android.Manifest;
import android.app.Activity;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.net.Uri;
import android.provider.Settings;
import android.support.v4.app.ActivityCompat;
import android.support.v4.content.ContextCompat;
/** Helper to ask camera permission. */
public class PermissionHelper {
public static final int CAMERA_CODE = 0;
public static final int READ_EXTERNAL_STORAGE_CODE = 1;
public static final int WRITE_EXTERNAL_STORAGE_CODE = 2;
public static final int INTERNET_CODE = 3;
public static final int ACCESS_NETWORK_STATE_CODE = 4;
public static final int ACCESS_FINE_LOCATION_CODE = 5;
public static final int ACCESS_WIFI_STATE_CODE = 6;
/** Check to see we have the necessary permissions for this app. */
public static boolean hasPermission(Activity activity, String permission) {
return ContextCompat.checkSelfPermission(activity, permission) == PackageManager.PERMISSION_GRANTED;
}
/** Check to see we have the necessary permissions for this app, and ask for them if we don't. */
public static void requestPermission(Activity activity, String permission) {
int requestCode = -1;
if (permission == Manifest.permission.CAMERA) {
requestCode = CAMERA_CODE;
} else if(permission == Manifest.permission.READ_EXTERNAL_STORAGE) {
requestCode = READ_EXTERNAL_STORAGE_CODE;
} else if(permission == Manifest.permission.WRITE_EXTERNAL_STORAGE) {
requestCode = WRITE_EXTERNAL_STORAGE_CODE;
} else if(permission == Manifest.permission.INTERNET) {
requestCode = INTERNET_CODE;
} else if(permission == Manifest.permission.ACCESS_NETWORK_STATE) {
requestCode = ACCESS_NETWORK_STATE_CODE;
} else if(permission == Manifest.permission.ACCESS_FINE_LOCATION) {
requestCode = ACCESS_FINE_LOCATION_CODE;
} else if(permission == Manifest.permission.ACCESS_WIFI_STATE) {
requestCode = ACCESS_WIFI_STATE_CODE;
}
if(requestCode >=0)
{
ActivityCompat.requestPermissions(
activity, new String[] {permission}, requestCode);
}
}
/** Check to see if we need to show the rationale for this permission. */
public static boolean shouldShowRequestPermissionRationale(Activity activity, String permission) {
return ActivityCompat.shouldShowRequestPermissionRationale(activity, permission);
}
/** Launch Application Setting to grant permission. */
public static void launchPermissionSettings(Activity activity) {
Intent intent = new Intent();
intent.setAction(Settings.ACTION_APPLICATION_DETAILS_SETTINGS);
intent.setData(Uri.fromParts("package", activity.getPackageName(), null));
activity.startActivity(intent);
}
}
File diff suppressed because it is too large Load Diff
@@ -1,5 +1,10 @@
package com.introlab.rtabmap; package com.introlab.rtabmap;
import java.nio.ByteBuffer;
import java.nio.FloatBuffer;
import android.app.Activity;
import android.content.Context;
import android.os.IBinder; import android.os.IBinder;
import android.view.KeyEvent; import android.view.KeyEvent;
import android.util.Log; import android.util.Log;
@@ -15,7 +20,7 @@ public class RTABMapLib
// the correct library first. // the correct library first.
if (TangoInitializationHelper.loadTangoSharedLibrary() == if (TangoInitializationHelper.loadTangoSharedLibrary() ==
TangoInitializationHelper.ARCH_ERROR) { TangoInitializationHelper.ARCH_ERROR) {
Log.e(RTABMapActivity.class.getSimpleName(), "ERROR! Unable to load libtango_client_api.so!"); Log.w(RTABMapActivity.class.getSimpleName(), "WArning! Unable to load libtango_client_api.so! This can be safely ignored if RTAB-Map NDK is not build with tango support.");
} }
System.loadLibrary("NativeRTABMap"); System.loadLibrary("NativeRTABMap");
} }
@@ -23,87 +28,86 @@ public class RTABMapLib
// Initialize the Tango Service, this function starts the communication // Initialize the Tango Service, this function starts the communication
// between the application and Tango Service. // between the application and Tango Service.
// 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 long createNativeApplication(RTABMapActivity activity);
public static native void setScreenRotation(int displayRotation, int cameraRotation); public static native void destroyNativeApplication(long nativeApplication);
public static native int openDatabase(String databasePath, boolean databaseInMemory, boolean optimize); public static native void setScreenRotation(long nativeApplication, int displayRotation, int cameraRotation);
public static native int openDatabase2(String databaseSource, String databasePath, boolean databaseInMemory, boolean optimize);
/* public static native int openDatabase(long nativeApplication, String databasePath, boolean databaseInMemory, boolean optimize, boolean clearDatabase);
* Called when the Tango service is connected.
* public static native boolean recover(long nativeApplication, String from, String to);
* @param binder The native binder object.
*/
public static native boolean onTangoServiceConnected(IBinder binder);
// Release all non OpenGl resources that are allocated from the program. public static native boolean isBuiltWith(long nativeApplication, int cameraDriver);
public static native void onPause(); public static native boolean startCamera(long nativeApplication, IBinder binder, Context context, Activity activity, int driver);
public static native void stopCamera(long nativeApplication);
// Allocate OpenGL resources for rendering. // Allocate OpenGL resources for rendering.
public static native void initGlContent(); public static native void initGlContent(long nativeApplication);
// Setup the view port width and height. // Setup the view port width and height.
public static native void setupGraphic(int width, int height); public static native void setupGraphic(long nativeApplication, int width, int height);
// Main render loop. // Main render loop.
public static native int render(); public static native int render(long nativeApplication);
// Set the render camera's viewing angle: // Set the render camera's viewing angle:
// first person, third person, or top down. // first person, third person, or top down.
public static native void setCamera(int cameraIndex); public static native void setCamera(long nativeApplication, int cameraIndex);
// Pass touch events to the native layer. // Pass touch events to the native layer.
public static native void onTouchEvent(int touchCount, int event0, public static native void onTouchEvent(long nativeApplication, int touchCount, int event0,
float x0, float y0, float x1, float y1); float x0, float y0, float x1, float y1);
public static native void setPausedMapping(long nativeApplication, boolean paused);
public static native void setPausedMapping(boolean paused); public static native void setOnlineBlending(long nativeApplication, boolean enabled);
public static native void setOnlineBlending(boolean enabled); public static native void setMapCloudShown(long nativeApplication, boolean shown);
public static native void setMapCloudShown(boolean shown); public static native void setOdomCloudShown(long nativeApplication, boolean shown);
public static native void setOdomCloudShown(boolean shown); public static native void setMeshRendering(long nativeApplication, boolean enabled, boolean withTexture);
public static native void setMeshRendering(boolean enabled, boolean withTexture); public static native void setLocalizationMode(long nativeApplication, boolean enabled);
public static native void setLocalizationMode(boolean enabled); public static native void setTrajectoryMode(long nativeApplication, boolean enabled);
public static native void setTrajectoryMode(boolean enabled); public static native void setGraphOptimization(long nativeApplication, boolean enabled);
public static native void setGraphOptimization(boolean enabled); public static native void setNodesFiltering(long nativeApplication, boolean enabled);
public static native void setNodesFiltering(boolean enabled); public static native void setGraphVisible(long nativeApplication, boolean visible);
public static native void setGraphVisible(boolean visible); public static native void setGridVisible(long nativeApplication, boolean visible);
public static native void setGridVisible(boolean visible); public static native void setRawScanSaved(long nativeApplication, boolean enabled);
public static native void setRawScanSaved(boolean enabled); public static native void setFullResolution(long nativeApplication, boolean enabled);
public static native void setFullResolution(boolean enabled); public static native void setSmoothing(long nativeApplication, boolean enabled);
public static native void setSmoothing(boolean enabled); public static native void setDepthFromMotion(long nativeApplication, boolean enabled);
public static native void setCameraColor(boolean enabled); public static native void setCameraColor(long nativeApplication, boolean enabled);
public static native void setAppendMode(boolean enabled); public static native void setAppendMode(long nativeApplication, boolean enabled);
public static native void setDataRecorderMode(boolean enabled); public static native void setDataRecorderMode(long nativeApplication, boolean enabled);
public static native void setMaxCloudDepth(float value); public static native void setMaxCloudDepth(long nativeApplication, float value);
public static native void setMinCloudDepth(float value); public static native void setMinCloudDepth(long nativeApplication, float value);
public static native void setPointSize(float value); public static native void setPointSize(long nativeApplication, float value);
public static native void setFOV(float value); public static native void setFOV(long nativeApplication, float value);
public static native void setOrthoCropFactor(float value); public static native void setOrthoCropFactor(long nativeApplication, float value);
public static native void setGridRotation(float value); public static native void setGridRotation(long nativeApplication, float value);
public static native void setLighting(boolean enabled); public static native void setLighting(long nativeApplication, boolean enabled);
public static native void setBackfaceCulling(boolean enabled); public static native void setBackfaceCulling(long nativeApplication, boolean enabled);
public static native void setWireframe(boolean enabled); public static native void setWireframe(long nativeApplication, boolean enabled);
public static native void setCloudDensityLevel(int value); public static native void setCloudDensityLevel(long nativeApplication, int value);
public static native void setMeshAngleTolerance(float value); public static native void setMeshAngleTolerance(long nativeApplication, float value);
public static native void setMeshTriangleSize(int value); public static native void setMeshTriangleSize(long nativeApplication, int value);
public static native void setClusterRatio(float value); public static native void setClusterRatio(long nativeApplication, float value);
public static native void setMaxGainRadius(float value); public static native void setMaxGainRadius(long nativeApplication, float value);
public static native void setRenderingTextureDecimation(int value); public static native void setRenderingTextureDecimation(long nativeApplication, int value);
public static native void setBackgroundColor(float gray); public static native void setBackgroundColor(long nativeApplication, float gray);
public static native int setMappingParameter(String key, String value); public static native int setMappingParameter(long nativeApplication, String key, String value);
public static native void setGPS( public static native void setGPS(
long nativeApplication,
double stamp, double stamp,
double longitude, double longitude,
double latitude, double latitude,
double altitude, double altitude,
double accuracy, double accuracy,
double bearing); double bearing);
public static native void addEnvSensor(long nativeApplication, int type, float value);
public static native void resetMapping(); public static native void save(long nativeApplication, String outputDatabasePath);
public static native void save(String outputDatabasePath); public static native void cancelProcessing(long nativeApplication);
public static native void cancelProcessing();
public static native boolean exportMesh( public static native boolean exportMesh(
long nativeApplication,
float cloudVoxelSize, float cloudVoxelSize,
boolean regenerateCloud, boolean regenerateCloud,
boolean meshing, boolean meshing,
@@ -120,15 +124,41 @@ public class RTABMapLib
float optimizedMaxTextureDistance, float optimizedMaxTextureDistance,
int optimizedMinTextureClusterSize, int optimizedMinTextureClusterSize,
boolean blockRendering); boolean blockRendering);
public static native boolean writeExportedMesh(String directory, String name); public static native boolean writeExportedMesh(long nativeApplication, String directory, String name);
public static native boolean postExportation(boolean visualize); public static native boolean postExportation(long nativeApplication, boolean visualize);
public static native int postProcessing(int approach); public static native int postProcessing(long nativeApplication, int approach);
public static native String getStatus(); public static native String getStatus(long nativeApplication);
public static native int getTotalNodes(); public static native int getTotalNodes(long nativeApplication);
public static native int getTotalWords(); public static native int getTotalWords(long nativeApplication);
public static native int getTotalPoints(); public static native int getTotalPoints(long nativeApplication);
public static native float getUpdateTime(); public static native float getUpdateTime(long nativeApplication);
public static native int getLoopClosureId(); public static native int getLoopClosureId(long nativeApplication);
public static native void postCameraPoseEvent(long nativeApplication, float x, float y, float z, float qx, float qy, float qz, float qw, double stamp);
public static native void postOdometryEvent(long nativeApplication,
float x, float y, float z, float qx, float qy, float qz, float qw,
float rgb_fx, float rgb_fy, float rgb_cx, float rgb_cy,
float rgbFrameX, float rgbFrameY, float rgbFrameZ, float rgbFrameQX, float rgbFrameQY, float rgbFrameQZ, float rgbFrameQW,
double stamp,
ByteBuffer yPlane, ByteBuffer uPlane, ByteBuffer vPlane, int yPlaneLen, int rgbWidth, int rgbHeight, int rgbFormat,
FloatBuffer points, int pointsLen,
float vx, float vy, float vz, float vqx, float vqy, float vqz, float vqw, //view matrix
float p00, float p11, float p02, float p12, float p22, float p32, float p23, // projection matrix
float t0, float t1, float t2, float t3, float t4, float t5, float t6, float t7); // tex coord
public static native void postOdometryEventDepth(long nativeApplication,
float x, float y, float z, float qx, float qy, float qz, float qw,
float rgb_fx, float rgb_fy, float rgb_cx, float rgb_cy,
float depth_fx, float depth_fy, float depth_cx, float depth_cy,
float rgbFrameX, float rgbFrameY, float rgbFrameZ, float rgbFrameQX, float rgbFrameQY, float rgbFrameQZ, float rgbFrameQW,
float depthFrameX, float depthFrameY, float depthFrameZ, float depthFrameQX, float depthFrameQY, float depthFrameQZ, float depthFrameQW,
double rgbStamp,
double depthStamp,
ByteBuffer yPlane, ByteBuffer uPlane, ByteBuffer vPlane, int yPlaneLen, int rgbWidth, int rgbHeight, int rgbFormat,
ByteBuffer depth, int depthLen, int depthWidth, int depthHeight, int depthFormat,
FloatBuffer points, int pointsLen,
float vx, float vy, float vz, float vqx, float vqy, float vqz, float vqw, //view matrix
float p00, float p11, float p02, float p12, float p22, float p32, float p23, // projection matrix
float t0, float t1, float t2, float t3, float t4, float t5, float t6, float t7); // tex coord
} }
@@ -43,12 +43,15 @@ public class Renderer implements GLSurfaceView.Renderer {
private float mSurfaceHeight = 0.0f; private float mSurfaceHeight = 0.0f;
private float mTextColor = 1.0f; private float mTextColor = 1.0f;
private int mOffset = 0; private int mOffset = 0;
private ARCoreSharedCamera mCamera = null;
private DisplayRotationHelper mDisplayRotationHelper = null;
private Vector<TextObject> mTexts; private Vector<TextObject> mTexts;
private static RTABMapActivity mActivity; private static RTABMapActivity mActivity;
public Renderer(RTABMapActivity c) { public Renderer(RTABMapActivity c) {
mActivity = c; mActivity = c;
mDisplayRotationHelper = new DisplayRotationHelper(/*context=*/ c);
} }
private ProgressDialog mProgressDialog = null; private ProgressDialog mProgressDialog = null;
@@ -71,91 +74,129 @@ public class Renderer implements GLSurfaceView.Renderer {
{ {
mOffset = offset; mOffset = offset;
} }
public void setCamera(ARCoreSharedCamera camera)
{
mCamera = camera;
if(mCamera!=null)
{
mDisplayRotationHelper.onDisplayChanged(0);
mDisplayRotationHelper.updateSessionIfNeeded(mCamera);
}
}
// Render loop of the Gl context. // Render loop of the Gl context.
public void onDrawFrame(GL10 useGLES20instead) { public void onDrawFrame(GL10 useGLES20instead) {
try synchronized (this) {
{ if(mActivity.nativeApplication != 0)
final int value = RTABMapLib.render();
if(mTextManager!=null)
{ {
if(mTextChanged) int step = 0;
try
{ {
mTextChanged = false; if(mCamera!=null)
Vector<TextObject> txtcollection = new Vector<TextObject>();
mTextLock.lock();
try {
if(mTexts.size() > 0)
{
txtcollection.addAll(mTexts);
}
} finally {
mTextLock.unlock();
}
// Prepare the text for rendering
mTextManager.PrepareDraw(txtcollection);
}
float[] mvp = new float[16];
Matrix.translateM(mvp, 0, mtrxProjectionAndView, 0, 0, mOffset, 0);
mTextManager.Draw(mvp);
}
if(value != 0 && mProgressDialog != null && mProgressDialog.isShowing())
{
mActivity.runOnUiThread(new Runnable() {
public void run() {
if(!RTABMapActivity.DISABLE_LOG) Log.i("RTABMapActivity", "Renderer: dismiss dialog, value received=" + String.valueOf(value));
mProgressDialog.dismiss();
mActivity.resetNoTouchTimer();
}
});
}
if(value==-1)
{
mActivity.runOnUiThread(new Runnable() {
public void run() {
if(mToast!=null)
{
mToast.makeText(mActivity, String.format("Out of Memory!"), Toast.LENGTH_SHORT).show();
}
}
});
}
else if(value==-2)
{
mActivity.runOnUiThread(new Runnable() {
public void run() {
if(mToast!=null)
{
mToast.makeText(mActivity, String.format("Rendering Error!"), Toast.LENGTH_SHORT).show();
}
}
});
}
}
catch(final Exception e)
{
mActivity.runOnUiThread(new Runnable() {
public void run() {
if(mToast!=null)
{ {
mToast.makeText(mActivity, String.format("Rendering error! %s", e.getMessage()), Toast.LENGTH_SHORT).show(); step=1;
mCamera.updateGL();
}
step=2;
final int value = RTABMapLib.render(mActivity.nativeApplication);
if(mTextManager!=null)
{
step=3;
if(mTextChanged)
{
mTextChanged = false;
Vector<TextObject> txtcollection = new Vector<TextObject>();
mTextLock.lock();
try {
if(mTexts.size() > 0)
{
txtcollection.addAll(mTexts);
}
} finally {
mTextLock.unlock();
}
// Prepare the text for rendering
mTextManager.PrepareDraw(txtcollection);
}
float[] mvp = new float[16];
Matrix.translateM(mvp, 0, mtrxProjectionAndView, 0, 0, mOffset, 0);
mTextManager.Draw(mvp);
}
step=4;
if(value != 0 && mProgressDialog != null && mProgressDialog.isShowing())
{
mActivity.runOnUiThread(new Runnable() {
public void run() {
if(!RTABMapActivity.DISABLE_LOG) Log.i("RTABMapActivity", "Renderer: dismiss dialog, value received=" + String.valueOf(value));
mProgressDialog.dismiss();
mActivity.resetNoTouchTimer();
}
});
}
if(value==-1)
{
mActivity.runOnUiThread(new Runnable() {
public void run() {
if(mToast!=null)
{
mToast.makeText(mActivity.getApplicationContext(), String.format("Out of Memory!"), Toast.LENGTH_SHORT).show();
}
}
});
}
else if(value==-2)
{
mActivity.runOnUiThread(new Runnable() {
public void run() {
if(mToast!=null)
{
mToast.makeText(mActivity.getApplicationContext(), String.format("Rendering Error!"), Toast.LENGTH_SHORT).show();
}
}
});
} }
} }
catch(final Exception e)
}); {
final int stepF = step;
mActivity.runOnUiThread(new Runnable() {
public void run() {
if(mToast!=null)
{
String msg = String.format("Rendering error! (exception=%s) step=%d", e.getMessage(), stepF);
Log.e("RTABMapActivity", msg);
mToast.makeText(mActivity.getApplicationContext(), msg, Toast.LENGTH_LONG).show();
}
}
});
}
}
} }
} }
// Called when the surface size changes. // Called when the surface size changes.
public void onSurfaceChanged(GL10 useGLES20instead, int width, int height) { public void onSurfaceChanged(GL10 useGLES20instead, int width, int height) {
RTABMapLib.setupGraphic(width, height); if(mActivity.nativeApplication!=0)
{
RTABMapLib.setupGraphic(mActivity.nativeApplication, width, height);
}
mDisplayRotationHelper.onSurfaceChanged(width, height);
if(mCamera!=null)
{
mDisplayRotationHelper.updateSessionIfNeeded(mCamera);
}
mSurfaceHeight = (float)height; mSurfaceHeight = (float)height;
@@ -180,7 +221,10 @@ public class Renderer implements GLSurfaceView.Renderer {
// Called when the surface is created or recreated. // Called when the surface is created or recreated.
public void onSurfaceCreated(GL10 useGLES20instead, EGLConfig config) { public void onSurfaceCreated(GL10 useGLES20instead, EGLConfig config) {
RTABMapLib.initGlContent(); if(mActivity.nativeApplication != 0)
{
RTABMapLib.initGlContent(mActivity.nativeApplication);
}
// Create our text manager // Create our text manager
mTextManager = new TextManager(mActivity); mTextManager = new TextManager(mActivity);
@@ -7,11 +7,14 @@ import java.util.Arrays;
import java.util.Iterator; import java.util.Iterator;
import java.util.Map.Entry; import java.util.Map.Entry;
import android.Manifest;
import android.app.AlertDialog; import android.app.AlertDialog;
import android.content.DialogInterface; import android.content.DialogInterface;
import android.content.SharedPreferences; import android.content.SharedPreferences;
import android.content.SharedPreferences.OnSharedPreferenceChangeListener; import android.content.SharedPreferences.OnSharedPreferenceChangeListener;
import android.content.pm.PackageManager;
import android.os.Bundle; import android.os.Bundle;
import android.preference.CheckBoxPreference;
import android.preference.ListPreference; import android.preference.ListPreference;
import android.preference.Preference; import android.preference.Preference;
import android.preference.PreferenceActivity; import android.preference.PreferenceActivity;
@@ -19,6 +22,7 @@ import android.text.InputType;
import android.view.WindowManager; import android.view.WindowManager;
import android.view.inputmethod.EditorInfo; import android.view.inputmethod.EditorInfo;
import android.widget.EditText; import android.widget.EditText;
import android.widget.Toast;
public class SettingsActivity extends PreferenceActivity implements OnSharedPreferenceChangeListener { public class SettingsActivity extends PreferenceActivity implements OnSharedPreferenceChangeListener {
@@ -34,7 +38,7 @@ public class SettingsActivity extends PreferenceActivity implements OnSharedPref
@Override @Override
public boolean onPreferenceClick(Preference preference) { public boolean onPreferenceClick(Preference preference) {
getPreferenceScreen().getSharedPreferences().edit().clear().commit(); getPreferenceScreen().getSharedPreferences().edit().clear().commit();
recreate(); recreate();
return true; return true;
@@ -184,7 +188,31 @@ public class SettingsActivity extends PreferenceActivity implements OnSharedPref
} }
}); });
Preference buttonGPS = findPreference(getString(R.string.pref_key_gps_saved));
buttonGPS.setOnPreferenceClickListener(new Preference.OnPreferenceClickListener() {
@Override
public boolean onPreferenceClick(Preference preference) {
if(((CustomSwitchPreference)preference).isChecked())
{
if (!PermissionHelper.hasPermission(getActivity(), Manifest.permission.ACCESS_FINE_LOCATION)) {
((CustomSwitchPreference)preference).setChecked(false);
PermissionHelper.requestPermission(getActivity(), Manifest.permission.ACCESS_FINE_LOCATION);
return false;
}
}
return true;
}
});
if(((CustomSwitchPreference)buttonGPS).isChecked())
{
if (!PermissionHelper.hasPermission(this, Manifest.permission.ACCESS_FINE_LOCATION)) {
((CustomSwitchPreference)buttonGPS).setChecked(false);
PermissionHelper.requestPermission(this, Manifest.permission.ACCESS_FINE_LOCATION);
}
}
((Preference)findPreference(getString(R.string.pref_key_camera_driver))).setSummary("("+((ListPreference)findPreference(getString(R.string.pref_key_camera_driver))).getEntry() + ") "+getString(R.string.pref_summary_camera_driver));
((Preference)findPreference(getString(R.string.pref_key_density))).setSummary("("+((ListPreference)findPreference(getString(R.string.pref_key_density))).getEntry() + ") "+getString(R.string.pref_summary_density)); ((Preference)findPreference(getString(R.string.pref_key_density))).setSummary("("+((ListPreference)findPreference(getString(R.string.pref_key_density))).getEntry() + ") "+getString(R.string.pref_summary_density));
((Preference)findPreference(getString(R.string.pref_key_depth))).setSummary("("+((ListPreference)findPreference(getString(R.string.pref_key_depth))).getEntry() + ") "+getString(R.string.pref_summary_depth)); ((Preference)findPreference(getString(R.string.pref_key_depth))).setSummary("("+((ListPreference)findPreference(getString(R.string.pref_key_depth))).getEntry() + ") "+getString(R.string.pref_summary_depth));
((Preference)findPreference(getString(R.string.pref_key_min_depth))).setSummary("("+((ListPreference)findPreference(getString(R.string.pref_key_min_depth))).getEntry() + ") "+getString(R.string.pref_summary_min_depth)); ((Preference)findPreference(getString(R.string.pref_key_min_depth))).setSummary("("+((ListPreference)findPreference(getString(R.string.pref_key_min_depth))).getEntry() + ") "+getString(R.string.pref_summary_min_depth));
@@ -194,6 +222,7 @@ public class SettingsActivity extends PreferenceActivity implements OnSharedPref
((Preference)findPreference(getString(R.string.pref_key_background_color))).setSummary("("+((ListPreference)findPreference(getString(R.string.pref_key_background_color))).getEntry() + ") "+getString(R.string.pref_summary_background_color)); ((Preference)findPreference(getString(R.string.pref_key_background_color))).setSummary("("+((ListPreference)findPreference(getString(R.string.pref_key_background_color))).getEntry() + ") "+getString(R.string.pref_summary_background_color));
((Preference)findPreference(getString(R.string.pref_key_rendering_texture_decimation))).setSummary("("+((ListPreference)findPreference(getString(R.string.pref_key_rendering_texture_decimation))).getEntry() + ") "+getString(R.string.pref_summary_rendering_texture_decimation)); ((Preference)findPreference(getString(R.string.pref_key_rendering_texture_decimation))).setSummary("("+((ListPreference)findPreference(getString(R.string.pref_key_rendering_texture_decimation))).getEntry() + ") "+getString(R.string.pref_summary_rendering_texture_decimation));
((Preference)findPreference(getString(R.string.pref_key_arcore_localization_filtering_speed))).setSummary("("+((ListPreference)findPreference(getString(R.string.pref_key_arcore_localization_filtering_speed))).getEntry() + ") "+getString(R.string.pref_summary_arcore_localization_filtering_speed));
((Preference)findPreference(getString(R.string.pref_key_update_rate))).setSummary("("+((ListPreference)findPreference(getString(R.string.pref_key_update_rate))).getEntry() + ") "+getString(R.string.pref_summary_update_rate)); ((Preference)findPreference(getString(R.string.pref_key_update_rate))).setSummary("("+((ListPreference)findPreference(getString(R.string.pref_key_update_rate))).getEntry() + ") "+getString(R.string.pref_summary_update_rate));
((Preference)findPreference(getString(R.string.pref_key_max_speed))).setSummary("("+((ListPreference)findPreference(getString(R.string.pref_key_max_speed))).getEntry() + ") "+getString(R.string.pref_summary_max_speed)); ((Preference)findPreference(getString(R.string.pref_key_max_speed))).setSummary("("+((ListPreference)findPreference(getString(R.string.pref_key_max_speed))).getEntry() + ") "+getString(R.string.pref_summary_max_speed));
((Preference)findPreference(getString(R.string.pref_key_time_thr))).setSummary("("+((ListPreference)findPreference(getString(R.string.pref_key_time_thr))).getEntry() + ") "+getString(R.string.pref_summary_time_thr)); ((Preference)findPreference(getString(R.string.pref_key_time_thr))).setSummary("("+((ListPreference)findPreference(getString(R.string.pref_key_time_thr))).getEntry() + ") "+getString(R.string.pref_summary_time_thr));
@@ -206,6 +235,8 @@ public class SettingsActivity extends PreferenceActivity implements OnSharedPref
((Preference)findPreference(getString(R.string.pref_key_features))).setSummary("("+((ListPreference)findPreference(getString(R.string.pref_key_features))).getEntry() + ") "+getString(R.string.pref_summary_features)); ((Preference)findPreference(getString(R.string.pref_key_features))).setSummary("("+((ListPreference)findPreference(getString(R.string.pref_key_features))).getEntry() + ") "+getString(R.string.pref_summary_features));
((Preference)findPreference(getString(R.string.pref_key_features_type))).setSummary("("+((ListPreference)findPreference(getString(R.string.pref_key_features_type))).getEntry() + ") "+getString(R.string.pref_summary_features_type)); ((Preference)findPreference(getString(R.string.pref_key_features_type))).setSummary("("+((ListPreference)findPreference(getString(R.string.pref_key_features_type))).getEntry() + ") "+getString(R.string.pref_summary_features_type));
((Preference)findPreference(getString(R.string.pref_key_optimizer))).setSummary("("+((ListPreference)findPreference(getString(R.string.pref_key_optimizer))).getEntry() + ") "+getString(R.string.pref_summary_optimizer)); ((Preference)findPreference(getString(R.string.pref_key_optimizer))).setSummary("("+((ListPreference)findPreference(getString(R.string.pref_key_optimizer))).getEntry() + ") "+getString(R.string.pref_summary_optimizer));
((Preference)findPreference(getString(R.string.pref_key_marker_detection))).setSummary("("+((ListPreference)findPreference(getString(R.string.pref_key_marker_detection))).getEntry() + ") "+getString(R.string.pref_summary_marker_detection));
((Preference)findPreference(getString(R.string.pref_key_marker_detection_depth_error))).setSummary("("+((ListPreference)findPreference(getString(R.string.pref_key_marker_detection_depth_error))).getEntry() + ") "+getString(R.string.pref_summary_marker_detection_depth_error));
((Preference)findPreference(getString(R.string.pref_key_cloud_voxel))).setSummary("("+((ListPreference)findPreference(getString(R.string.pref_key_cloud_voxel))).getEntry() + ") "+getString(R.string.pref_summary_cloud_voxel)); ((Preference)findPreference(getString(R.string.pref_key_cloud_voxel))).setSummary("("+((ListPreference)findPreference(getString(R.string.pref_key_cloud_voxel))).getEntry() + ") "+getString(R.string.pref_summary_cloud_voxel));
((Preference)findPreference(getString(R.string.pref_key_texture_size))).setSummary("("+((ListPreference)findPreference(getString(R.string.pref_key_texture_size))).getEntry() + ") "+getString(R.string.pref_summary_texture_size)); ((Preference)findPreference(getString(R.string.pref_key_texture_size))).setSummary("("+((ListPreference)findPreference(getString(R.string.pref_key_texture_size))).getEntry() + ") "+getString(R.string.pref_summary_texture_size));
@@ -226,6 +257,7 @@ public class SettingsActivity extends PreferenceActivity implements OnSharedPref
Preference pref = findPreference(key); Preference pref = findPreference(key);
if (pref instanceof ListPreference) { if (pref instanceof ListPreference) {
if(key.compareTo(getString(R.string.pref_key_camera_driver))==0) pref.setSummary("("+ ((ListPreference)pref).getEntry() + ") "+getString(R.string.pref_summary_camera_driver));
if(key.compareTo(getString(R.string.pref_key_density))==0) pref.setSummary("("+ ((ListPreference)pref).getEntry() + ") "+getString(R.string.pref_summary_density)); if(key.compareTo(getString(R.string.pref_key_density))==0) pref.setSummary("("+ ((ListPreference)pref).getEntry() + ") "+getString(R.string.pref_summary_density));
if(key.compareTo(getString(R.string.pref_key_depth))==0) if(key.compareTo(getString(R.string.pref_key_depth))==0)
{ {
@@ -253,6 +285,7 @@ public class SettingsActivity extends PreferenceActivity implements OnSharedPref
if(key.compareTo(getString(R.string.pref_key_background_color))==0) pref.setSummary("("+((ListPreference)pref).getEntry() + ") "+getString(R.string.pref_summary_background_color)); if(key.compareTo(getString(R.string.pref_key_background_color))==0) pref.setSummary("("+((ListPreference)pref).getEntry() + ") "+getString(R.string.pref_summary_background_color));
if(key.compareTo(getString(R.string.pref_key_rendering_texture_decimation))==0) pref.setSummary("("+((ListPreference)pref).getEntry() + ") "+getString(R.string.pref_summary_rendering_texture_decimation)); if(key.compareTo(getString(R.string.pref_key_rendering_texture_decimation))==0) pref.setSummary("("+((ListPreference)pref).getEntry() + ") "+getString(R.string.pref_summary_rendering_texture_decimation));
if(key.compareTo(getString(R.string.pref_key_arcore_localization_filtering_speed))==0) pref.setSummary("("+((ListPreference)pref).getEntry() + ") "+getString(R.string.pref_summary_arcore_localization_filtering_speed));
if(key.compareTo(getString(R.string.pref_key_update_rate))==0) pref.setSummary("("+((ListPreference)pref).getEntry() + ") "+getString(R.string.pref_summary_update_rate)); if(key.compareTo(getString(R.string.pref_key_update_rate))==0) pref.setSummary("("+((ListPreference)pref).getEntry() + ") "+getString(R.string.pref_summary_update_rate));
if(key.compareTo(getString(R.string.pref_key_max_speed))==0) pref.setSummary("("+((ListPreference)pref).getEntry() + ") "+getString(R.string.pref_summary_max_speed)); if(key.compareTo(getString(R.string.pref_key_max_speed))==0) pref.setSummary("("+((ListPreference)pref).getEntry() + ") "+getString(R.string.pref_summary_max_speed));
if(key.compareTo(getString(R.string.pref_key_time_thr))==0) pref.setSummary("("+((ListPreference)pref).getEntry() + ") "+getString(R.string.pref_summary_time_thr)); if(key.compareTo(getString(R.string.pref_key_time_thr))==0) pref.setSummary("("+((ListPreference)pref).getEntry() + ") "+getString(R.string.pref_summary_time_thr));
@@ -265,6 +298,8 @@ public class SettingsActivity extends PreferenceActivity implements OnSharedPref
if(key.compareTo(getString(R.string.pref_key_features))==0) pref.setSummary("("+((ListPreference)pref).getEntry() + ") "+getString(R.string.pref_summary_features)); if(key.compareTo(getString(R.string.pref_key_features))==0) pref.setSummary("("+((ListPreference)pref).getEntry() + ") "+getString(R.string.pref_summary_features));
if(key.compareTo(getString(R.string.pref_key_features_type))==0) pref.setSummary("("+((ListPreference)pref).getEntry() + ") "+getString(R.string.pref_summary_features_type)); if(key.compareTo(getString(R.string.pref_key_features_type))==0) pref.setSummary("("+((ListPreference)pref).getEntry() + ") "+getString(R.string.pref_summary_features_type));
if(key.compareTo(getString(R.string.pref_key_optimizer))==0) pref.setSummary("("+((ListPreference)pref).getEntry() + ") "+getString(R.string.pref_summary_optimizer)); if(key.compareTo(getString(R.string.pref_key_optimizer))==0) pref.setSummary("("+((ListPreference)pref).getEntry() + ") "+getString(R.string.pref_summary_optimizer));
if(key.compareTo(getString(R.string.pref_key_marker_detection))==0) pref.setSummary("("+((ListPreference)pref).getEntry() + ") "+getString(R.string.pref_summary_marker_detection));
if(key.compareTo(getString(R.string.pref_key_marker_detection_depth_error))==0) pref.setSummary("("+((ListPreference)pref).getEntry() + ") "+getString(R.string.pref_summary_marker_detection_depth_error));
if(key.compareTo(getString(R.string.pref_key_cloud_voxel))==0) pref.setSummary("("+((ListPreference)pref).getEntry() + ") "+getString(R.string.pref_summary_cloud_voxel)); if(key.compareTo(getString(R.string.pref_key_cloud_voxel))==0) pref.setSummary("("+((ListPreference)pref).getEntry() + ") "+getString(R.string.pref_summary_cloud_voxel));
if(key.compareTo(getString(R.string.pref_key_texture_size))==0) pref.setSummary("("+((ListPreference)pref).getEntry() + ") "+getString(R.string.pref_summary_texture_size)); if(key.compareTo(getString(R.string.pref_key_texture_size))==0) pref.setSummary("("+((ListPreference)pref).getEntry() + ") "+getString(R.string.pref_summary_texture_size));
@@ -327,4 +362,28 @@ public class SettingsActivity extends PreferenceActivity implements OnSharedPref
} }
ed.commit(); //save it. ed.commit(); //save it.
} }
@Override
public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] results) {
switch (requestCode) {
case PermissionHelper.ACCESS_FINE_LOCATION_CODE: {
// If request is cancelled, the result arrays are empty.
if (results.length > 0 && results[0] == PackageManager.PERMISSION_GRANTED) {
// permission was granted, yay! Do the
// contacts-related task you need to do.
Preference buttonGPS = findPreference(getString(R.string.pref_key_gps_saved));
((CustomSwitchPreference)buttonGPS).setChecked(true);
} else {
// permission denied, boo! Disable the
// functionality that depends on this permission.
Toast.makeText(this, "Location permission is needed to use GPS functionality", Toast.LENGTH_LONG).show();
if (!PermissionHelper.shouldShowRequestPermissionRationale(this, Manifest.permission.ACCESS_FINE_LOCATION)) {
PermissionHelper.launchPermissionSettings(this); // Permission denied with checking "Do not ask again".
}
}
return;
}
}
}
} }
@@ -66,6 +66,7 @@ public class SketchfabActivity extends Activity implements OnClickListener {
mButtonOk = (Button)findViewById(R.id.button_ok); mButtonOk = (Button)findViewById(R.id.button_ok);
mProgressDialog = new ProgressDialog(this); mProgressDialog = new ProgressDialog(this);
mProgressDialog.setCancelable(false);
mProgressDialog.setCanceledOnTouchOutside(false); mProgressDialog.setCanceledOnTouchOutside(false);
mAuthToken = getIntent().getExtras().getString(RTABMapActivity.RTABMAP_AUTH_TOKEN_KEY); mAuthToken = getIntent().getExtras().getString(RTABMapActivity.RTABMAP_AUTH_TOKEN_KEY);
@@ -142,7 +143,8 @@ public class SketchfabActivity extends Activity implements OnClickListener {
if(!isNetworkAvailable()) if(!isNetworkAvailable())
{ {
// Visualize the result? // Visualize the result?
new AlertDialog.Builder(this) AlertDialog ad = new AlertDialog.Builder(this)
.setCancelable(false)
.setTitle("Sharing to Sketchfab...") .setTitle("Sharing to Sketchfab...")
.setMessage("Network is not available. Make sure you have internet before continuing.") .setMessage("Network is not available. Make sure you have internet before continuing.")
.setPositiveButton("Try Again", new DialogInterface.OnClickListener() { .setPositiveButton("Try Again", new DialogInterface.OnClickListener() {
@@ -154,7 +156,9 @@ public class SketchfabActivity extends Activity implements OnClickListener {
public void onClick(DialogInterface dialog, int which) { public void onClick(DialogInterface dialog, int which) {
} }
}) })
.show(); .create();
ad.setCanceledOnTouchOutside(false);
ad.show();
return; return;
} }
@@ -165,6 +169,8 @@ public class SketchfabActivity extends Activity implements OnClickListener {
WebView web; WebView web;
mAuthDialog = new Dialog(this); mAuthDialog = new Dialog(this);
mAuthDialog.setCancelable(true);
mAuthDialog.setCanceledOnTouchOutside(true);
mAuthDialog.setContentView(R.layout.auth_dialog); mAuthDialog.setContentView(R.layout.auth_dialog);
web = (WebView)mAuthDialog.findViewById(R.id.webv); web = (WebView)mAuthDialog.findViewById(R.id.webv);
web.setWebContentsDebuggingEnabled(!RTABMapActivity.DISABLE_LOG); web.setWebContentsDebuggingEnabled(!RTABMapActivity.DISABLE_LOG);
@@ -200,7 +206,6 @@ public class SketchfabActivity extends Activity implements OnClickListener {
}); });
mAuthDialog.show(); mAuthDialog.show();
mAuthDialog.setTitle("Authorize RTAB-Map"); mAuthDialog.setTitle("Authorize RTAB-Map");
mAuthDialog.setCancelable(true);
web.loadUrl(auth_url); web.loadUrl(auth_url);
} }
else else
@@ -213,6 +218,8 @@ public class SketchfabActivity extends Activity implements OnClickListener {
{ {
mProgressDialog.setTitle("Upload to Sketchfab"); mProgressDialog.setTitle("Upload to Sketchfab");
mProgressDialog.setMessage(String.format("Compressing the files...")); mProgressDialog.setMessage(String.format("Compressing the files..."));
mProgressDialog.setCancelable(false);
mProgressDialog.setCanceledOnTouchOutside(false);
mProgressDialog.show(); mProgressDialog.show();
Thread workingThread = new Thread(new Runnable() { Thread workingThread = new Thread(new Runnable() {
@@ -238,7 +245,7 @@ public class SketchfabActivity extends Activity implements OnClickListener {
File exportDir = new File(mWorkingDirectory + RTABMapActivity.RTABMAP_EXPORT_DIR); File exportDir = new File(mWorkingDirectory + RTABMapActivity.RTABMAP_EXPORT_DIR);
exportDir.mkdirs(); exportDir.mkdirs();
if(RTABMapLib.writeExportedMesh(mWorkingDirectory + RTABMapActivity.RTABMAP_TMP_DIR, RTABMapActivity.RTABMAP_TMP_FILENAME)) if(RTABMapLib.writeExportedMesh(RTABMapActivity.nativeApplication, mWorkingDirectory + RTABMapActivity.RTABMAP_TMP_DIR, RTABMapActivity.RTABMAP_TMP_FILENAME))
{ {
String[] files = new String[0]; String[] files = new String[0];
// verify if we have all files // verify if we have all files
@@ -308,7 +315,10 @@ public class SketchfabActivity extends Activity implements OnClickListener {
// do nothing... // do nothing...
} }
}); });
builder.show(); AlertDialog ad = builder.create();
ad.setCancelable(false);
ad.setCanceledOnTouchOutside(false);
ad.show();
} }
}); });
} }
@@ -371,6 +381,7 @@ public class SketchfabActivity extends Activity implements OnClickListener {
finish(); finish();
} }
}).create(); }).create();
d.setCanceledOnTouchOutside(false);
d.show(); d.show();
((TextView)d.findViewById(android.R.id.message)).setMovementMethod(LinkMovementMethod.getInstance()); ((TextView)d.findViewById(android.R.id.message)).setMovementMethod(LinkMovementMethod.getInstance());
} }
@@ -0,0 +1,265 @@
package com.introlab.rtabmap;
import android.graphics.ImageFormat;
import android.hardware.camera2.CameraAccessException;
import android.hardware.camera2.CameraCaptureSession;
import android.hardware.camera2.CameraDevice;
import android.hardware.camera2.CameraManager;
import android.hardware.camera2.CaptureFailure;
import android.hardware.camera2.CaptureRequest;
import android.hardware.camera2.TotalCaptureResult;
import android.media.Image;
import android.media.ImageReader;
import android.os.Handler;
import android.os.HandlerThread;
import android.support.annotation.NonNull;
import android.util.Log;
import android.view.Surface;
import java.nio.ByteBuffer;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
public class TOF_ImageReader implements ImageReader.OnImageAvailableListener {
public static final String TAG = TOF_ImageReader.class.getSimpleName();
public int WIDTH;
public int HEIGHT;
public ImageReader imageReader;
public int frameCount = 0;
public long timestamp;
// Looper handler thread.
private HandlerThread backgroundThread;
// Looper handler.
public Handler backgroundHandler;
public ByteBuffer depth16_raw;
// Camera capture session.
private CameraCaptureSession captureSession = null;
// Camera device.
private CameraDevice cameraDevice = null;
// Camera preview capture request builder
private CaptureRequest.Builder previewCaptureRequestBuilder;
TOF_ImageReader(){
}
public void close()
{
Log.i(TAG, "close()");
if (captureSession != null) {
captureSession.close();
captureSession = null;
}
if (cameraDevice != null) {
cameraDevice.close();
cameraDevice = null;
}
if (imageReader != null) {
imageReader.close();
imageReader = null;
}
}
// Camera device state callback.
public final CameraDevice.StateCallback cameraDeviceCallback =
new CameraDevice.StateCallback() {
@Override
public void onOpened(@NonNull CameraDevice cameraDevice) {
Log.d(TAG, "Camera depth ID " + cameraDevice.getId() + " opened.");
TOF_ImageReader.this.cameraDevice = cameraDevice;
createCameraPreviewSession();
}
@Override
public void onClosed(@NonNull CameraDevice cameraDevice) {
Log.d(TAG, "Camera device ID " + cameraDevice.getId() + " closed.");
TOF_ImageReader.this.cameraDevice = null;
}
@Override
public void onDisconnected(@NonNull CameraDevice cameraDevice) {
Log.w(TAG, "Camera depth ID " + cameraDevice.getId() + " disconnected.");
cameraDevice.close();
TOF_ImageReader.this.cameraDevice = null;
}
@Override
public void onError(@NonNull CameraDevice cameraDevice, int error) {
Log.e(TAG, "Camera depth ID " + cameraDevice.getId() + " error " + error);
cameraDevice.close();
TOF_ImageReader.this.cameraDevice = null;
}
};
private CameraCaptureSession.StateCallback captureStateCallback = new CameraCaptureSession.StateCallback() {
// Called when the camera capture session is first configured after the app
// is initialized, and again each time the activity is resumed.
@Override
public void onConfigured(@NonNull CameraCaptureSession session) {
Log.d(TAG, "Camera capture session configured.");
captureSession = session;
setRepeatingCaptureRequest();
}
@Override
public void onSurfacePrepared(
@NonNull CameraCaptureSession session, @NonNull Surface surface) {
Log.d(TAG, "Camera capture surface prepared.");
}
@Override
public void onReady(@NonNull CameraCaptureSession session) {
Log.d(TAG, "Camera capture session ready.");
}
@Override
public void onActive(@NonNull CameraCaptureSession session) {
Log.d(TAG, "Camera capture session active.");
}
@Override
public void onClosed(@NonNull CameraCaptureSession session) {
Log.d(TAG, "Camera capture session closed.");
}
@Override
public void onConfigureFailed(@NonNull CameraCaptureSession session) {
Log.e(TAG, "Failed to configure camera capture session.");
}
};
// Repeating camera capture session capture callback.
private final CameraCaptureSession.CaptureCallback captureSessionCallback =
new CameraCaptureSession.CaptureCallback() {
@Override
public void onCaptureCompleted(
@NonNull CameraCaptureSession session,
@NonNull CaptureRequest request,
@NonNull TotalCaptureResult result) {
//Log.i(TAG, "onCaptureCompleted");
}
//@Override // android 23
public void onCaptureBufferLost(
@NonNull CameraCaptureSession session,
@NonNull CaptureRequest request,
@NonNull Surface target,
long frameNumber) {
Log.e(TAG, "onCaptureBufferLost: " + frameNumber);
}
@Override
public void onCaptureFailed(
@NonNull CameraCaptureSession session,
@NonNull CaptureRequest request,
@NonNull CaptureFailure failure) {
Log.e(TAG, "onCaptureFailed: " + failure.getFrameNumber() + " " + failure.getReason());
}
@Override
public void onCaptureSequenceAborted(
@NonNull CameraCaptureSession session, int sequenceId) {
Log.e(TAG, "onCaptureSequenceAborted: " + sequenceId + " " + session);
}
};
// Called when starting non-AR mode or switching to non-AR mode.
// Also called when app starts in AR mode, or resumes in AR mode.
private void setRepeatingCaptureRequest() {
try {
captureSession.setRepeatingRequest(
previewCaptureRequestBuilder.build(), captureSessionCallback, backgroundHandler);
} catch (CameraAccessException e) {
Log.e(TAG, "Failed to set repeating request", e);
}
}
private void createCameraPreviewSession() {
Log.e(TAG, "createCameraPreviewSession: " + "starting camera preview session.");
frameCount = 0;
try {
// Create an ARCore compatible capture request using `TEMPLATE_RECORD`.
previewCaptureRequestBuilder = cameraDevice.createCaptureRequest(CameraDevice.TEMPLATE_RECORD);
previewCaptureRequestBuilder.addTarget(imageReader.getSurface());
// Create camera capture session for camera preview using callback.
cameraDevice.createCaptureSession(Arrays.asList(imageReader.getSurface()), captureStateCallback, backgroundHandler);
} catch (CameraAccessException e) {
Log.e(TAG, "CameraAccessException", e);
}
}
public void createImageReader(int width, int height){
Log.w(TAG, String.valueOf(width) + "x" + String.valueOf(height));
WIDTH = width;
HEIGHT = height;
this.imageReader =
ImageReader.newInstance(
width,
height,
ImageFormat.DEPTH16,
2);
this.imageReader.setOnImageAvailableListener(this, this.backgroundHandler);
}
// CPU image reader callback.
@Override
public void onImageAvailable(ImageReader imageReader) {
Image image = imageReader.acquireLatestImage();
if (image == null) {
Log.w(TAG, "onImageAvailable: Skipping null image.");
return;
}
else{
if(image.getFormat() == ImageFormat.DEPTH16){
synchronized (this) {
depth16_raw = image.getPlanes()[0].getBuffer().asReadOnlyBuffer();
timestamp = image.getTimestamp();
}
// copy raw undecoded DEPTH16 format depth data to NativeBuffer
frameCount++;
}
else{
Log.w(TAG, "onImageAvailable: depth image not in DEPTH16 format, skipping image");
}
}
image.close();
}
// Start background handler thread, used to run callbacks without blocking UI thread.
public void startBackgroundThread() {
this.backgroundThread = new HandlerThread("DepthDecoderThread");
this.backgroundThread.start();
this.backgroundHandler = new Handler(backgroundThread.getLooper());
}
// Stop background handler thread.
public void stopBackgroundThread() {
if (this.backgroundThread != null) {
this.backgroundThread.quitSafely();
try {
this.backgroundThread.join();
this.backgroundThread = null;
this.backgroundHandler = null;
} catch (InterruptedException e) {
Log.e(TAG, "Interrupted while trying to join depth background handler thread", e);
}
}
}
}
@@ -17,6 +17,7 @@ import android.graphics.Typeface;
import android.opengl.GLES20; import android.opengl.GLES20;
import android.opengl.GLUtils; import android.opengl.GLUtils;
import android.text.TextPaint; import android.text.TextPaint;
import android.util.Log;
public class TextManager { public class TextManager {
@@ -50,7 +51,7 @@ public class TextManager {
public static final int RI_TEXT_TEXTURE_SIZE = 512; // 512 public static final int RI_TEXT_TEXTURE_SIZE = 512; // 512
public static final float RI_TEXT_HEIGHT_BASE = 32.0f; public static final float RI_TEXT_HEIGHT_BASE = 32.0f;
public static final char RI_TEXT_START = ' '; public static final char RI_TEXT_START = ' ';
public static final char RI_TEXT_STOP = '~'+1; public static final char RI_TEXT_STOP = '\u00B0'+1;
public float getMaxTextHeight() {return mTextHeight;} public float getMaxTextHeight() {return mTextHeight;}
@@ -336,6 +337,8 @@ public class TextManager {
float y = val.y; float y = val.y;
String text = val.text; String text = val.text;
Log.i("RTABMapActivity", String.format("convertTextToTriangleInfo() set status=%s", text));
// Create // Create
for(int j=0; j<text.length(); j++) for(int j=0; j<text.length(); j++)
{ {
+24 -1
View File
@@ -7,7 +7,11 @@ import java.io.FileInputStream;
import java.io.FileOutputStream; import java.io.FileOutputStream;
import java.io.FilenameFilter; import java.io.FilenameFilter;
import java.io.IOException; import java.io.IOException;
import java.util.ArrayList;
import java.util.Arrays; import java.util.Arrays;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
import java.util.zip.ZipEntry; import java.util.zip.ZipEntry;
import java.util.zip.ZipOutputStream; import java.util.zip.ZipOutputStream;
@@ -55,7 +59,7 @@ public class Util {
} }
} }
public static String[] loadFileList(String directory, final boolean databasesOnly) { public static String[] loadFileList(final String directory, final boolean databasesOnly) {
File path = new File(directory); File path = new File(directory);
String fileList[]; String fileList[];
try { try {
@@ -83,6 +87,25 @@ public class Util {
}; };
fileList = path.list(filter); fileList = path.list(filter);
Arrays.sort(fileList); Arrays.sort(fileList);
List<String> fileListt = new ArrayList<String>(Arrays.asList(fileList));
Collections.sort(fileListt, new Comparator<String>() {
@Override
public int compare(String filename1, String filename2) {
File file1 = new File(directory+"/"+filename1);
File file2 = new File(directory+"/"+filename2);
long k = file1.lastModified() - file2.lastModified();
if(k > 0){
return -1;
}else if(k == 0){
return 0;
}else{
return 1;
}
}
});
fileListt.toArray(fileList);
} }
else { else {
fileList = new String[0]; fileList = new String[0];
+68
View File
@@ -0,0 +1,68 @@
# Xcode
#
# gitignore contributors: remember to update Global/Xcode.gitignore, Objective-C.gitignore & Swift.gitignore
## User settings
xcuserdata/
## compatibility with Xcode 8 and earlier (ignoring not required starting Xcode 9)
*.xcscmblueprint
*.xccheckout
## compatibility with Xcode 3 and earlier (ignoring not required starting Xcode 4)
build/
DerivedData/
*.moved-aside
*.pbxuser
!default.pbxuser
*.mode1v3
!default.mode1v3
*.mode2v3
!default.mode2v3
*.perspectivev3
!default.perspectivev3
## Obj-C/Swift specific
*.hmap
## App packaging
*.ipa
*.dSYM.zip
*.dSYM
# CocoaPods
#
# We recommend against adding the Pods directory to your .gitignore. However
# you should judge for yourself, the pros and cons are mentioned at:
# https://guides.cocoapods.org/using/using-cocoapods.html#should-i-check-the-pods-directory-into-source-control
#
# Pods/
#
# Add this line if you want to avoid checking in source code from the Xcode workspace
# *.xcworkspace
# Carthage
#
# Add this line if you want to avoid checking in source code from Carthage dependencies.
# Carthage/Checkouts
Carthage/Build/
# fastlane
#
# It is recommended to not store the screenshots in the git repo.
# Instead, use fastlane to re-generate the screenshots whenever they are needed.
# For more information about the recommended setup visit:
# https://docs.fastlane.tools/best-practices/source-control/#source-control
fastlane/report.xml
fastlane/Preview.html
fastlane/screenshots/**/*.png
fastlane/test_output
# Code Injection
#
# After new code Injection tools there's a generated folder /iOSInjectionProject
# https://github.com/johnno1962/injectionforxcode
iOSInjectionProject/
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<Workspace
version = "1.0">
<FileRef
location = "self:">
</FileRef>
</Workspace>
@@ -0,0 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>IDEDidComputeMac32BitWarning</key>
<true/>
</dict>
</plist>
@@ -0,0 +1,16 @@
{
"object": {
"pins": [
{
"package": "Zip",
"repositoryURL": "https://github.com/marmelroy/Zip.git",
"state": {
"branch": null,
"revision": "bd19d974e8a38cc8d3a88c90c8a107386c3b8ccf",
"version": "2.1.1"
}
}
]
},
"version": 1
}
@@ -0,0 +1,79 @@
<?xml version="1.0" encoding="UTF-8"?>
<Scheme
LastUpgradeVersion = "1230"
version = "1.3">
<BuildAction
parallelizeBuildables = "YES"
buildImplicitDependencies = "YES">
<BuildActionEntries>
<BuildActionEntry
buildForTesting = "YES"
buildForRunning = "YES"
buildForProfiling = "YES"
buildForArchiving = "YES"
buildForAnalyzing = "YES">
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "4EE015C1259A2AF0008CCE65"
BuildableName = "RTABMapApp.app"
BlueprintName = "RTABMapApp"
ReferencedContainer = "container:RTABMapApp.xcodeproj">
</BuildableReference>
</BuildActionEntry>
</BuildActionEntries>
</BuildAction>
<TestAction
buildConfiguration = "Debug"
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
shouldUseLaunchSchemeArgsEnv = "YES">
<Testables>
</Testables>
</TestAction>
<LaunchAction
buildConfiguration = "Release"
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
launchStyle = "0"
useCustomWorkingDirectory = "NO"
ignoresPersistentStateOnLaunch = "NO"
debugDocumentVersioning = "YES"
debugServiceExtension = "internal"
enableGPUFrameCaptureMode = "2"
allowLocationSimulation = "YES">
<BuildableProductRunnable
runnableDebuggingMode = "0">
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "4EE015C1259A2AF0008CCE65"
BuildableName = "RTABMapApp.app"
BlueprintName = "RTABMapApp"
ReferencedContainer = "container:RTABMapApp.xcodeproj">
</BuildableReference>
</BuildableProductRunnable>
</LaunchAction>
<ProfileAction
buildConfiguration = "Release"
shouldUseLaunchSchemeArgsEnv = "YES"
savedToolIdentifier = ""
useCustomWorkingDirectory = "NO"
debugDocumentVersioning = "YES">
<BuildableProductRunnable
runnableDebuggingMode = "0">
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "4EE015C1259A2AF0008CCE65"
BuildableName = "RTABMapApp.app"
BlueprintName = "RTABMapApp"
ReferencedContainer = "container:RTABMapApp.xcodeproj">
</BuildableReference>
</BuildableProductRunnable>
</ProfileAction>
<AnalyzeAction
buildConfiguration = "Debug">
</AnalyzeAction>
<ArchiveAction
buildConfiguration = "Release"
revealArchiveInOrganizer = "YES">
</ArchiveAction>
</Scheme>
+1
View File
@@ -0,0 +1 @@
Libraries
+76
View File
@@ -0,0 +1,76 @@
//
// AppDelegate.swift
// GLKittutorial
//
// Created by Mathieu Labbe on 2020-12-28.
//
import UIKit
import ARKit
func setDefaultsFromSettingsBundle() {
let plistFiles = ["Root", "Mapping", "Assembling"]
for plistName in plistFiles {
//Read PreferenceSpecifiers from Root.plist in Settings.Bundle
if let settingsURL = Bundle.main.url(forResource: plistName, withExtension: "plist", subdirectory: "Settings.bundle"),
let settingsPlist = NSDictionary(contentsOf: settingsURL),
let preferences = settingsPlist["PreferenceSpecifiers"] as? [NSDictionary] {
for prefSpecification in preferences {
if let key = prefSpecification["Key"] as? String, let value = prefSpecification["DefaultValue"] {
//If key doesn't exists in userDefaults then register it, else keep original value
if UserDefaults.standard.value(forKey: key) == nil {
UserDefaults.standard.set(value, forKey: key)
NSLog("registerDefaultsFromSettingsBundle: Set following to UserDefaults - (key: \(key), value: \(value), type: \(type(of: value)))")
}
}
}
} else {
NSLog("registerDefaultsFromSettingsBundle: Could not find Settings.bundle")
}
}
}
@main
class AppDelegate: UIResponder, UIApplicationDelegate {
var window: UIWindow?
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
// Always set Version to default
let defaults = UserDefaults.standard
defaults.removeObject(forKey: "Version")
setDefaultsFromSettingsBundle()
// Override point for customization after application launch.
if !ARWorldTrackingConfiguration.supportsFrameSemantics(.sceneDepth) {
// Ensure that the device supports scene depth and present
// an error-message view controller, if not.
let storyboard = UIStoryboard(name: "Main", bundle: nil)
window?.rootViewController = storyboard.instantiateViewController(withIdentifier: "unsupportedDeviceMessage")
}
return true
}
// MARK: UISceneSession Lifecycle
func application(_ application: UIApplication, configurationForConnecting connectingSceneSession: UISceneSession, options: UIScene.ConnectionOptions) -> UISceneConfiguration {
// Called when a new scene session is being created.
// Use this method to select a configuration to create the new scene with.
return UISceneConfiguration(name: "Default Configuration", sessionRole: connectingSceneSession.role)
}
func application(_ application: UIApplication, didDiscardSceneSessions sceneSessions: Set<UISceneSession>) {
// Called when the user discards a scene session.
// If any sessions were discarded while the application was not running, this will be called shortly after application:didFinishLaunchingWithOptions.
// Use this method to release any resources that were specific to the discarded scenes, as they will not return.
}
}
@@ -0,0 +1,11 @@
{
"colors" : [
{
"idiom" : "universal"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}
@@ -0,0 +1,116 @@
{
"images" : [
{
"filename" : "RTAB-Map40-1.png",
"idiom" : "iphone",
"scale" : "2x",
"size" : "20x20"
},
{
"filename" : "RTAB-Map60.png",
"idiom" : "iphone",
"scale" : "3x",
"size" : "20x20"
},
{
"filename" : "RTAB-Map58-1.png",
"idiom" : "iphone",
"scale" : "2x",
"size" : "29x29"
},
{
"filename" : "RTAB-Map87.png",
"idiom" : "iphone",
"scale" : "3x",
"size" : "29x29"
},
{
"filename" : "RTAB-Map80-1.png",
"idiom" : "iphone",
"scale" : "2x",
"size" : "40x40"
},
{
"filename" : "RTAB-Map120-1.png",
"idiom" : "iphone",
"scale" : "3x",
"size" : "40x40"
},
{
"filename" : "RTAB-Map120.png",
"idiom" : "iphone",
"scale" : "2x",
"size" : "60x60"
},
{
"filename" : "RTAB-Map180.png",
"idiom" : "iphone",
"scale" : "3x",
"size" : "60x60"
},
{
"filename" : "RTAB-Map20.png",
"idiom" : "ipad",
"scale" : "1x",
"size" : "20x20"
},
{
"filename" : "RTAB-Map40.png",
"idiom" : "ipad",
"scale" : "2x",
"size" : "20x20"
},
{
"filename" : "RTAB-Map29.png",
"idiom" : "ipad",
"scale" : "1x",
"size" : "29x29"
},
{
"filename" : "RTAB-Map58.png",
"idiom" : "ipad",
"scale" : "2x",
"size" : "29x29"
},
{
"filename" : "RTAB-Map40-2.png",
"idiom" : "ipad",
"scale" : "1x",
"size" : "40x40"
},
{
"filename" : "RTAB-Map80.png",
"idiom" : "ipad",
"scale" : "2x",
"size" : "40x40"
},
{
"filename" : "RTAB-Map76.png",
"idiom" : "ipad",
"scale" : "1x",
"size" : "76x76"
},
{
"filename" : "RTAB-Map152.png",
"idiom" : "ipad",
"scale" : "2x",
"size" : "76x76"
},
{
"filename" : "RTAB-Map167.png",
"idiom" : "ipad",
"scale" : "2x",
"size" : "83.5x83.5"
},
{
"filename" : "RTAB-Map1024.png",
"idiom" : "ios-marketing",
"scale" : "1x",
"size" : "1024x1024"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}
Binary file not shown.

After

Width:  |  Height:  |  Size: 442 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 16 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 16 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 23 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 26 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 26 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 14 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 14 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 14 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.5 KiB

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