Compare commits

...

1025 Commits

Author SHA1 Message Date
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
matlabbe
fa31affea0 Pnp multicam refactoring (#902)
* gui: fixed wrongly showing landmark rejected when it was not (because a loop closure was rejected at the same time)

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

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

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

* loc/small movement: cleanup bidirectional links

* Cov/PnP: fixed objPt transform to estimate depth

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

* Fixed marker detection on camera index> 0

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

* Fixed build without opengv

* Cmake: moved OpenGV dependency status under solvers group

* Added multi-stereocamera models support

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

* Fixed multicam 3d points generated from stereo correspondences

* db: Fixed multi stereo models not loaded correctly

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

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

* depthai: added imu firmware update option for convenience

* Fixed various refactor errors

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

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

* fixed compilation errors with latest opencv

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

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

* Marker: added priors variance parameters

* g2o: refactored backward compatibility includes

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

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

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

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

View File

@@ -33,36 +33,41 @@ install:
- set OPENNI2_LIB64=C:\Program Files\OpenNI2\Lib
- set OPENNI2_REDIST64=C:\Program Files\OpenNI2\Redist
# 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
- cmd: opencv-3.3.1-vc14.exe -o"C:\Program Files" -y
#- appveyor-retry appveyor DownloadFile http://downloads.sourceforge.net/project/opencvlibrary/4.5.2/opencv-4.5.2-vc14_vc15.exe
#- cmd: opencv-4.5.2-vc14_vc15.exe -o"C:\Program Files" -y
#- ECHO "Installed OpenCV:"
#- ps: "ls \"C:/Program Files/opencv/build\""
#- set PATH=%PATH%;C:\Program Files\opencv\build\x64\vc14\bin
- ps: wget 'https://dl.dropboxusercontent.com/s/o6ofn491bc0jso1/opencv450_vc14.exe?dl=0' -outfile opencv.exe
- cmd: opencv.exe -o"C:\Program Files" -y
- ECHO "Installed OpenCV:"
- ps: "ls \"C:/Program Files/opencv/build\""
- set PATH=%PATH%;C:\Program Files\opencv\build\x64\vc14\bin
- ps: "ls \"C:/Program Files/opencv\""
- set PATH=%PATH%;C:\Program Files\opencv\x64\vc14\bin
# VTK (including QVTK)
- ps: wget 'https://dl.dropboxusercontent.com/s/1l33b5l3f3y52gf/VTK-6_3-msvc140.exe?dl=0' -outfile VTK-6_3.exe
- cmd: VTK-6_3.exe -o"C:\Program Files" -y
- ECHO "Installed PCL:"
- ECHO "Installed VTK:"
- ps: "ls \"C:/Program Files/VTK\""
- set PATH=%PATH%;C:\Program Files\VTK\bin
# QHull
- ps: wget 'https://dl.dropboxusercontent.com/s/9widnk9msdsh2b8/Qhull-msvc140.exe?dl=0' -outfile Qhull.exe
- cmd: Qhull.exe -o"C:\Program Files" -y
- ECHO "Installed PCL:"
- ECHO "Installed QHull:"
- ps: "ls \"C:/Program Files/Qhull\""
- set PATH=%PATH%;C:\Program Files\Qhull\bin
# FLANN
- ps: wget 'https://dl.dropboxusercontent.com/s/7k58jbmqa51sxmh/FLANN-msvc140.exe?dl=0' -outfile FLANN.exe
- cmd: FLANN.exe -o"C:\Program Files" -y
- ECHO "Installed PCL:"
- ECHO "Installed FLANN:"
- ps: "ls \"C:/Program Files/FLANN\""
- set PATH=%PATH%;C:\Program Files\FLANN\bin
# Eigen
- ps: wget 'https://dl.dropboxusercontent.com/s/3v6i9i8dxj4o8ji/Eigen.exe?dl=0' -outfile Eigen.exe
- cmd: Eigen.exe -o"C:\Program Files" -y
- ECHO "Installed PCL:"
- ECHO "Installed Eigen:"
- ps: "ls \"C:/Program Files/Eigen\""
# 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
- ECHO "Installed PCL:"
- ps: "ls \"C:/Program Files/PCL\""
@@ -85,12 +90,49 @@ install:
- ECHO "Installed GTSAM:"
- ps: "ls \"C:/Program Files/GTSAM\""
- set PATH=%PATH%;C:\Program Files\GTSAM\bin
# OctoMap
- ps: wget 'https://dl.dropboxusercontent.com/s/6jpxu0nm8ne6e54/octomap_x64_vc14.exe?dl=0' -outfile octomap.exe
- cmd: octomap.exe -o"C:\Program Files" -y
- ECHO "Installed OctoMap:"
- ps: "ls \"C:/Program Files/octomap-distribution\""
- set PATH=%PATH%;C:\Program Files\octomap-distribution\bin
# CPU-TSDF
- ps: wget 'https://dl.dropboxusercontent.com/s/mgges9va1uzxr0q/cpu_tsdf_sept2015_x64_vc14.exe?dl=0' -outfile cpu_tsdf.exe
- cmd: cpu_tsdf.exe -o"C:\Program Files" -y
- ECHO "Installed CPU-TSDF:"
- ps: "ls \"C:/Program Files/cpu_tsdf\""
- set PATH=%PATH%;C:\Program Files\cpu_tsdf\bin
# Open Chisel
- ps: wget 'https://dl.dropboxusercontent.com/s/0aaphcde4acrinm/open_chisel_x64_vc14.exe?dl=0' -outfile open_chisel.exe
- cmd: open_chisel.exe -o"C:\Program Files" -y
- ECHO "Installed Open Chisel:"
- ps: "ls \"C:/Program Files/open_chisel\""
- set PATH=%PATH%;C:\Program Files\open_chisel\bin
# yaml-cpp
- ps: wget 'https://dl.dropboxusercontent.com/s/22qfvftwj6zq8tj/yaml-cpp_x64_vc14.exe?dl=0' -outfile yaml-cpp.exe
- cmd: yaml-cpp.exe -o"C:\Program Files" -y
- ECHO "Installed yaml-cpp:"
- ps: "ls \"C:/Program Files/yaml-cpp\""
# RealSense2
- ps: wget 'https://github.com/IntelRealSense/librealsense/releases/download/v2.40.0/Intel.RealSense.SDK-WIN10-2.40.0.2482.exe' -outfile realsense2.exe
- cmd: realsense2.exe /VERYSILENT
- ECHO "Installed RealSense2:"
- ps: "ls \"C:/Program Files (x86)/Intel RealSense SDK 2.0\""
- set PATH=%PATH%;C:\Program Files (x86)\Intel RealSense SDK 2.0\bin\x64
- set RealSense2_ROOT_DIR=C:\Program Files (x86)\Intel RealSense SDK 2.0
# Kinect 4 Azure
- ps: wget 'https://download.microsoft.com/download/3/d/6/3d6d9e99-a251-4cf3-8c6a-8e108e960b4b/Azure%20Kinect%20SDK%201.4.1.exe' -outfile azure.exe
- cmd: azure.exe /quiet
- ECHO "Installed Kinect For Azure:"
- ps: "ls \"C:/Program Files/Azure Kinect SDK v1.4.1\""
- set PATH=%PATH%;C:\Program Files\Azure Kinect SDK v1.4.1\tools
- set K4A_ROOT_DIR=C:\Program Files\Azure Kinect SDK v1.4.1
before_build:
- cd c:\projects\rtabmap\build
- ECHO %PROGRAMFILES%
- ECHO %PATH%
- cmake -G "Visual Studio 14 2015 Win64" -DOpenCV_DIR="C:\Program Files\opencv\build" -DPCL_DIR="C:\Program Files\PCL\cmake" -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 :
- cmake --build . --config Release --target package
@@ -101,7 +143,7 @@ artifacts:
notifications:
- provider: Email
to:
- matlabbe@email.com
- matlabbe@gmail.com
on_build_success: false
on_build_failure: false
on_build_status_changed: true

1
.dockerignore Normal file
View File

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

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

@@ -0,0 +1,64 @@
name: CMake-ROS
on:
push:
branches:
- '**'
pull_request:
branches:
- '**'
env:
# Customize the CMake build type here (Release, Debug, RelWithDebInfo, etc.)
BUILD_TYPE: Release
jobs:
build:
# The CMake configure and build commands are platform agnostic and should work equally
# well on Windows or Mac. You can convert this to a matrix build if you need
# cross-platform coverage.
# See: https://docs.github.com/en/free-pro-team@latest/actions/learn-github-actions/managing-complex-workflows#using-a-build-matrix
name: Build on ros ${{ matrix.ros_distribution }} and ${{ matrix.os }}
runs-on: ${{ matrix.os }}
strategy:
matrix:
ros_distribution: [melodic, noetic, foxy, humble, rolling]
include:
- ros_distribution: 'melodic'
os: ubuntu-18.04
- 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:
- uses: ros-tooling/setup-ros@v0.4
with:
required-ros-distributions: ${{ matrix.ros_distribution }}
- name: Install dependencies
run: |
sudo apt-get update
sudo apt-get -y install ros-${{ matrix.ros_distribution }}-rtabmap
sudo apt-get -y remove ros-${{ matrix.ros_distribution }}-rtabmap
- uses: actions/checkout@v2
- 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
.github/workflows/cmake.yml vendored Normal file
View File

@@ -0,0 +1,48 @@
name: CMake
on:
push:
branches:
- '**'
pull_request:
branches:
- '**'
env:
BUILD_TYPE: Release
jobs:
build:
name: ${{ matrix.os }}
runs-on: ${{ matrix.os }}
strategy:
matrix:
os: [ubuntu-22.04, ubuntu-20.04, ubuntu-18.04]
steps:
- name: Install dependencies
run: |
DEBIAN_FRONTEND=noninteractive
sudo apt-get update
sudo apt-get -y install libopencv-dev libpcl-dev git cmake software-properties-common 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}}

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

@@ -0,0 +1,111 @@
name: docker
on:
push:
branches:
- 'master'
jobs:
docker:
runs-on: ubuntu-latest
strategy:
matrix:
docker_tag: [xenial, bionic, focal, android23, android24, android26, android30]
include:
- docker_tag: xenial
docker_tags: |
introlab3it/rtabmap:xenial
introlab3it/rtabmap:16.04
docker_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: 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

2
.gitignore vendored
View File

@@ -8,3 +8,5 @@ app/android/.classpath
app/android/.project
app/android/AndroidManifest.xml
app/android/res/raw/
compile_flags.txt
tags

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

File diff suppressed because it is too large Load Diff

View File

@@ -1,5 +1,6 @@
Copyright (c) 2010-2016, Mathieu Labbe - IntRoLab - Universite de Sherbrooke
All rights reserved.
RTAB-Map - https://github.com/introlab/rtabmap
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
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
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
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
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.
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

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)
[![Release][release-image]][releases]
[![License][license-image]][license]
Linux: [![Build Status](https://travis-ci.org/introlab/rtabmap.svg?branch=master)](https://travis-ci.org/introlab/rtabmap) Windows: [![Build status](https://ci.appveyor.com/api/projects/status/hr73xspix9oqa26h/branch/master?svg=true)](https://ci.appveyor.com/project/matlabbe/rtabmap/branch/master)
[release-image]: https://img.shields.io/badge/release-0.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
[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.
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.
### 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>

View File

@@ -74,13 +74,16 @@ if(@CONF_WITH_GUI@ AND ${WITH_GUI})
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.")
MESSAGE(WARNING "Asked for \"gui\" module but RTABMap hasn't been built with gui support.")
endif()
# Dependencies
if(@CONF_VTK_QT@ AND ${WITH_GUI})
find_package(VTK COMPONENTS vtkGUISupportQt NO_MODULE) # to define vtkGUISupportQt target
endif(@CONF_VTK_QT@ AND ${WITH_GUI})
if(@CONF_DEPTH_AI@)
FIND_PACKAGE(depthai 2 QUIET REQUIRED)
endif(@CONF_DEPTH_AI@)
SET(RTABMap_LIBRARIES ${RTABMap_LIBRARIES} "@CONF_DEPENDENCIES@")
#backward compatibilities

View File

@@ -40,32 +40,61 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
@NONFREE@#define RTABMAP_NONFREE
@TORO@#define RTABMAP_TORO
@G2O@#define RTABMAP_G2O
@G2O_CPP_CONF@#define RTABMAP_G2O_CPP11
@G2O_CPP_CONF@#define RTABMAP_G2O_CPP11 @G2O_CPP11@
@GTSAM@#define RTABMAP_GTSAM
@CERES@#define RTABMAP_CERES
@VERTIGO@#define RTABMAP_VERTIGO
@OPENCV3@#define RTABMAP_OPENCV3
@OPENNI2@#define RTABMAP_OPENNI2
@FREENECT@#define RTABMAP_FREENECT
@FREENECT2@#define RTABMAP_FREENECT2
@K4W2@#define RTABMAP_K4W2
@K4A@#define RTABMAP_K4A
@CVSBA@#define RTABMAP_CVSBA
@POINTMATCHER@#define RTABMAP_POINTMATCHER
@CCCORELIB@#define RTABMAP_CCCORELIB
@OPEN3D@#define RTABMAP_OPEN3D
@FASTCV@#define RTABMAP_FASTCV
@OPENGV@#define RTABMAP_OPENGV
@PDAL@#define RTABMAP_PDAL
@LOAM@#define RTABMAP_LOAM
@FLOAM@#define RTABMAP_FLOAM
@DC1394@#define RTABMAP_DC1394
@FLYCAPTURE2@#define RTABMAP_FLYCAPTURE2
@ZED@#define RTABMAP_ZED
@ZEDOC@#define RTABMAP_ZEDOC
@REALSENSE@#define RTABMAP_REALSENSE
@REALSENSESLAM@#define RTABMAP_REALSENSE_SLAM
@REALSENSE2@#define RTABMAP_REALSENSE2
@MYNTEYE@#define RTABMAP_MYNTEYE
@DEPTHAI@#define RTABMAP_DEPTHAI
@OCTOMAP@#define RTABMAP_OCTOMAP
@CPUTSDF@#define RTABMAP_CPUTSDF
@ALICE_VISION@#define RTABMAP_ALICE_VISION
@OPENCHISEL@#define RTABMAP_OPENCHISEL
@FOVIS@#define RTABMAP_FOVIS
@VISO2@#define RTABMAP_VISO2
@DVO@#define RTABMAP_DVO
@OKVIS@#define RTABMAP_OKVIS
@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_ */

View File

@@ -1 +1,2 @@
/bin/
/gen/

View File

@@ -2,22 +2,26 @@
<!-- BEGIN_INCLUDE(manifest) -->
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.introlab.rtabmap"
android:versionCode="70"
android:versionCode="72"
android:versionName="@RTABMAP_VERSION@">
<uses-permission android:name="android.permission.CAMERA" />
<uses-permission android:name="android.permission.READ_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.ACCESS_NETWORK_STATE" />
<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:glEsVersion="0x00020000" />
<!-- This is the platform API where NativeActivity was introduced. -->
<uses-sdk android:minSdkVersion="19" />
<!-- This is the platform API where depth16 support in android was introduced. -->
<uses-sdk android:minSdkVersion="@ANDROID_NATIVE_API_LEVEL@" />
<queries>
<package android:name="com.google.ar.core" />
<package android:name="com.huawei.ar.engine" />
</queries>
<!-- This .apk has no Java code itself, so set hasCode to false. -->
<application
@@ -25,7 +29,9 @@
android:icon="@drawable/ic_launcher"
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.
This will take care of integrating with our NDK code. -->
@@ -41,11 +47,41 @@
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<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 android:name="SettingsActivity" android:label="@string/settings" 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>
</manifest>

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(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)
ADD_DEFINITIONS(-DDISABLE_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)
SET(ANDROID_DEBUGGABLE false)
@@ -29,7 +114,8 @@ endif()
configure_file(
"${CMAKE_CURRENT_SOURCE_DIR}/AndroidManifest.xml.in"
"${CMAKE_CURRENT_SOURCE_DIR}/AndroidManifest.xml")
"${CMAKE_CURRENT_SOURCE_DIR}/AndroidManifest.xml"
@ONLY)
configure_file(
"${CMAKE_CURRENT_SOURCE_DIR}/AndroidManifest.xml"

View File

@@ -0,0 +1,39 @@
/*
Copyright (c) 2010-2014, 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 UNIVERTY DE SHERBROOKE 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 CAMERAAVAILABILITY_H_
#define CAMERAAVAILABILITY_H_
// This is auto-generated!
@TANGO@#define RTABMAP_TANGO
@ARCORE@#define RTABMAP_ARCORE
@ARENGINE@#define RTABMAP_ARENGINE
#endif /* CAMERAAVAILABILITY_H_ */

View File

@@ -6,8 +6,8 @@
<copy todir="${native.libs.dir}/${android.abi}">
<fileset dir="${srcdir}/jni/third-party/lib" includes="*.so"/>
</copy>
<copy todir="${native.libs.dir}">
<fileset dir="${srcdir}/jni/third-party/lib" includes="${android.abi}/*.so"/>
</copy>
<copy todir="${native.libs.dir}">
<fileset dir="${srcdir}/jni/third-party/lib" includes="${android.abi}/*.so"/>
</copy>
</target>
</project>

View File

@@ -1,7 +1,7 @@
<h3>Real-Time Appearance-Based Mapping</h3>
Version @RTABMAP_VERSION@<br>
Author: Mathieu Labb&eacute;<br>
Copyright 2016-2017<br>
Copyright 2016-2020<br>
IntRoLab - Universit&eacute; de Sherbrooke<br>
<b>http://introlab.github.io/rtabmap</b><br><br>

1
app/android/jni/.gitignore vendored Normal file
View File

@@ -0,0 +1 @@
CameraAvailability.h

View File

@@ -1,35 +1,29 @@
find_package(Tango REQUIRED)
SET(INCLUDE_DIRS
${CMAKE_CURRENT_SOURCE_DIR}
${CMAKE_CURRENT_SOURCE_DIR}/tango-gl/include
${CMAKE_CURRENT_SOURCE_DIR}/third-party/include
${PROJECT_BINARY_DIR}/corelib/include
${PROJECT_SOURCE_DIR}/corelib/include
${PROJECT_SOURCE_DIR}/utilite/include
${OpenCV_INCLUDE_DIRS}
${PCL_INCLUDE_DIRS}
${Tango_INCLUDE_DIRS}
"${ANDROID_NDK}/platforms/android-${ANDROID_NATIVE_API_LEVEL}/arch-${ANDROID_ARCH_NAME}/usr/include"
)
SET(LIBRARIES
${OpenCV_LIBRARIES}
${PCL_LIBRARIES}
${Tango_LIBRARIES}
)
add_definitions(${PCL_DEFINITIONS})
INCLUDE_DIRECTORIES(${INCLUDE_DIRS})
set(sources
jni_interface.cpp
CameraTango.cpp
CameraMobile.cpp
RTABMapApp.cpp
scene.cpp
point_cloud_drawable.cpp
graph_drawable.cpp
background_renderer.cc
tango-gl/axis.cpp
tango-gl/camera.cpp
tango-gl/conversions.cpp
@@ -44,6 +38,82 @@ set(sources
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})
target_link_libraries(NativeRTABMap ${LIBRARIES}
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_DEBUG "${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)

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 */

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_ */

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 */

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_ */

View File

@@ -0,0 +1,461 @@
/*
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);
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 */

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_ */

View File

@@ -33,6 +33,7 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include "rtabmap/core/util2d.h"
#include <tango_client_api.h>
#include <tango_support_api.h>
#include "tango-gl/camera.h"
namespace rtabmap {
@@ -42,11 +43,22 @@ const int holeSize = 5;
const float maxDepthError = 0.10;
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
void onPointCloudAvailableRouter(void* context, const TangoPointCloud* point_cloud)
{
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);
}
@@ -55,34 +67,32 @@ void onPointCloudAvailableRouter(void* context, const TangoPointCloud* point_clo
void onFrameAvailableRouter(void* context, TangoCameraId id, const TangoImageBuffer* color)
{
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())
{
app->rgbReceived(tangoImage, (unsigned int)color->format, color->timestamp);
}
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())
{
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)
{
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
//////////////////////////////
const float CameraTango::bilateralFilteringSigmaS = 2.0f;
const float CameraTango::bilateralFilteringSigmaR = 0.075f;
CameraTango::CameraTango(bool colorCamera, int decimation, bool publishRawScan, bool smoothing) :
Camera(0),
CameraMobile(smoothing),
tango_config_(0),
previousStamp_(0.0),
stampEpochOffset_(0.0),
colorCamera_(colorCamera),
decimation_(decimation),
rawScanPublished_(publishRawScan),
smoothing_(smoothing),
cloudStamp_(0),
tangoColorType_(0),
tangoColorStamp_(0),
colorCameraToDisplayRotation_(ROTATION_0),
originUpdate_(false)
tangoColorStamp_(0)
{
UASSERT(decimation >= 1);
}
@@ -350,6 +351,7 @@ bool CameraTango::init(const std::string & calibrationFolder, const std::string
pose_data.orientation[1],
pose_data.orientation[2],
pose_data.orientation[3]);
deviceTColorCamera_ = rtabmap_world_T_opengl_world * deviceTColorCamera_;
// camera intrinsic
TangoCameraIntrinsics color_camera_intrinsics;
@@ -408,18 +410,14 @@ bool CameraTango::init(const std::string & calibrationFolder, const std::string
model_ = CameraModel(colorCamera_?"color":"fisheye",
cv::Size(color_camera_intrinsics.width, color_camera_intrinsics.height),
K, D, R, P,
tango_device_T_rtabmap_device.inverse()*deviceTColorCamera_); // device to camera optical rotation in rtabmap frame
deviceTColorCamera_);
if(!colorCamera_)
{
initFisheyeRectificationMap(model_, fisheyeRectifyMapX_, fisheyeRectifyMapY_);
}
LOGI("deviceTColorCameraTango =%s", deviceTColorCamera_.prettyPrint().c_str());
LOGI("deviceTColorCameraRtabmap=%s", (tango_device_T_rtabmap_device.inverse()*deviceTColorCamera_).prettyPrint().c_str());
cameraStartedTime_.restart();
LOGI("deviceTColorCameraRtabmap =%s", deviceTColorCamera_.prettyPrint().c_str());
return true;
}
@@ -433,23 +431,15 @@ void CameraTango::close()
TangoService_disconnect();
LOGI("TangoService_disconnect() done.");
}
previousPose_.setNull();
previousStamp_ = 0.0;
fisheyeRectifyMapX_ = cv::Mat();
fisheyeRectifyMapY_ = cv::Mat();
lastKnownGPS_ = GPS();
originOffset_ = Transform();
originUpdate_ = false;
}
void CameraTango::resetOrigin()
{
originUpdate_ = true;
CameraMobile::close();
}
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);
@@ -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
if(!tangoColor_.empty())
{
UTimer timer;
double dt = fabs(timestamp - tangoColorStamp_);
//LOGD("Depth: %f vs %f = %f", tangoColorStamp_, timestamp, dt);
if(dt >= 0.0 && dt < 0.5)
{
bool notify = cloud_.empty();
cloud_ = cloud.clone();
cloudStamp_ = timestamp;
bool notify = !data_.isValid();
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)
{
//LOGD("Cloud: Release semaphore");
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)
{
if(this->isRunning() && !tangoImage.empty())
if(!tangoImage.empty())
{
//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)
{
this->post(new CameraTangoEvent(type, key, value));
}
bool CameraTango::isCalibrated() const
{
return model_.isValidForProjection();
this->post(new CameraInfoEvent(type, key, value));
}
std::string CameraTango::getSerial() const
@@ -540,11 +727,6 @@ std::string CameraTango::getSerial() const
return "Tango";
}
void CameraTango::setGPS(const GPS & gps)
{
lastKnownGPS_ = gps;
}
rtabmap::Transform CameraTango::tangoPoseToTransform(const TangoPoseData * tangoPose) const
{
UASSERT(tangoPose);
@@ -587,8 +769,7 @@ rtabmap::Transform CameraTango::getPoseAtTimestamp(double timestamp)
}
else
{
pose = tangoPoseToTransform(&pose_start_service_T_device);
pose = rtabmap_world_T_tango_world * tangoPoseToTransform(&pose_start_service_T_device) * tango_device_T_rtabmap_world;
}
return pose;
@@ -598,375 +779,116 @@ SensorData CameraTango::captureImage(CameraInfo * info)
{
//LOGI("Capturing image...");
SensorData data;
if(!dataReady_.acquire(1, 2000))
if(textureId_ == 0)
{
if(this->isRunning())
{
LOGE("Not received any frames since 2 seconds, try to restart the camera again.");
this->post(new CameraTangoEvent(0, "CameraTango", "No frames received since 2 seconds."));
boost::mutex::scoped_lock lock(dataMutex_);
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;
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);
}
else
// Update Texture (optional, just for first-view rendering)
if(colorCamera_ && textureId_)
{
cv::Mat cloud;
cv::Mat tangoImage;
cv::Mat rgb;
double cloudStamp = 0.0;
double rgbStamp = 0.0;
int tangoColorType = 0;
double video_overlay_timestamp;
TangoErrorType status = TangoService_updateTextureExternalOes(TANGO_CAMERA_COLOR, textureId_, &video_overlay_timestamp);
if (status == TANGO_SUCCESS)
{
boost::mutex::scoped_lock lock(dataMutex_);
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)
if(info)
{
rgb = util2d::decimate(rgb, decimation_);
model = model.scaled(1.0/double(decimation_));
info->odomPose = getPoseAtTimestamp(video_overlay_timestamp);
}
}
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;
int rotation = static_cast<int>(getScreenRotation()) + 1; // remove 90deg camera rotation
if (rotation > 3) {
rotation -= 4;
}
// 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)
TangoDoubleMatrixTransformData matrix_transform;
status = TangoSupport_getDoubleMatrixTransformAtTime(
video_overlay_timestamp,
TANGO_COORDINATE_FRAME_CAMERA_COLOR,
TANGO_COORDINATE_FRAME_START_OF_SERVICE,
TANGO_SUPPORT_ENGINE_OPENGL,
TANGO_SUPPORT_ENGINE_OPENGL,
static_cast<TangoSupportRotation>(rotation),
&matrix_transform);
if (matrix_transform.status_code == TANGO_POSE_VALID)
{
float * p = cloud.ptr<float>(0,i);
cv::Point3f pt = util3d::transformPoint(cv::Point3f(p[0], p[1], p[2]), colorToDepth);
// Get projection matrix
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_)
{
scanData.at(oi++) = pt;
}
if (ret == TANGO_SUCCESS) {
float image_width = static_cast<float>(color_camera_intrinsics.width);
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;
// 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)
viewMatrix_ = glm::make_mat4(matrix_transform.matrix);
if(!getOriginOffset().isNull())
{
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;
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)
projectionMatrix_ = tango_gl::Camera::ProjectionMatrixForCameraIntrinsics(
image_width, image_height, fx, fy, cx, cy, 0.3, 50);
switch(rotation)
{
depthPixel = depth_value;
pixelSet = true;
case ROTATION_90:
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 &&
pixel_y_h>0 && pixel_y_h<depth.rows && // ignore first line
depth_value)
else
{
unsigned short & depthPixel = depth.at<unsigned short>(pixel_y_h, pixel_x_h);
if(depthPixel == 0 || depthPixel > depth_value)
{
depthPixel = depth_value;
pixelSet = true;
}
UERROR("TangoSupport_getCameraIntrinsicsBasedOnDisplayRotation failed!");
}
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
{
data = SensorData(rgb, depth, model, this->getNextSeqID(), rgbStamp);
}
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());
UERROR("TangoSupport_getDoubleMatrixTransformAtTime failed!");
}
}
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;
}
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 */

View File

@@ -28,6 +28,7 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#ifndef CAMERATANGO_H_
#define CAMERATANGO_H_
#include "CameraMobile.h"
#include <rtabmap/core/Camera.h>
#include <rtabmap/core/GeodeticCoords.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/UTimer.h>
#include <boost/thread/mutex.hpp>
#include <tango_client_api.h>
#include <tango_support_api.h>
class TangoPoseData;
namespace rtabmap {
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 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;
class CameraTango : public CameraMobile {
public:
CameraTango(bool colorCamera, int decimation, bool publishRawScan, bool smoothing);
virtual ~CameraTango();
virtual bool init(const std::string & calibrationFolder = ".", const std::string & cameraName = "");
void close(); // close Tango connection
void resetOrigin();
virtual bool isCalibrated() const;
virtual void close(); // close Tango connection
virtual std::string getSerial() const;
const CameraModel & getCameraModel() const {return model_;}
rtabmap::Transform tangoPoseToTransform(const TangoPoseData * tangoPose) const;
void setColorCamera(bool enabled) {if(!this->isRunning()) colorCamera_ = enabled;}
void setDecimation(int value) {decimation_ = value;}
void setSmoothing(bool enabled) {smoothing_ = 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 rgbReceived(const cv::Mat & tangoImage, int type, double timestamp);
void poseReceived(const Transform & pose);
void tangoEventReceived(int type, const char * key, const char * value);
protected:
@@ -104,34 +66,19 @@ protected:
private:
rtabmap::Transform getPoseAtTimestamp(double timestamp);
virtual void mainLoopBegin();
virtual void mainLoop();
private:
void * tango_config_;
Transform previousPose_;
double previousStamp_;
UTimer cameraStartedTime_;
double stampEpochOffset_;
bool colorCamera_;
int decimation_;
bool rawScanPublished_;
bool smoothing_;
cv::Mat cloud_;
double cloudStamp_;
SensorData data_;
cv::Mat tangoColor_;
int tangoColorType_;
double tangoColorStamp_;
boost::mutex dataMutex_;
USemaphore dataReady_;
CameraModel model_;
Transform deviceTColorCamera_;
TangoSupportRotation colorCameraToDisplayRotation_;
cv::Mat fisheyeRectifyMapX_;
cv::Mat fisheyeRectifyMapY_;
GPS lastKnownGPS_;
Transform originOffset_;
bool originUpdate_;
};
} /* namespace rtabmap */

View File

@@ -11,7 +11,9 @@
#include <rtabmap/core/ProgressState.h>
#include <rtabmap/utilite/ULogger.h>
#include <rtabmap/utilite/UEventsManager.h>
#ifdef __ANDROID__
#include <jni.h>
#endif
namespace rtabmap {
@@ -27,16 +29,29 @@ public:
class ProgressionStatus: public ProgressState, public UEventsHandler
{
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();
}
#ifdef __ANDROID__
void setJavaObjects(JavaVM * jvm, jobject rtabmap)
{
jvm_ = jvm;
rtabmap_ = rtabmap;
}
#else
void setSwiftCallback(void * classPtr, void(*callback)(void *, int, int))
{
swiftClassPtr_ = classPtr;
swiftCallback = callback;
}
#endif
void reset(int max)
{
@@ -82,6 +97,7 @@ protected:
count_ += ((ProgressEvent*)event)->count_;
// Call JAVA callback
bool success = false;
#ifdef __ANDROID__
if(jvm_ && rtabmap_)
{
JNIEnv *env = 0;
@@ -103,6 +119,16 @@ protected:
}
jvm_->DetachCurrentThread();
}
#else // APPLE
if(swiftClassPtr_)
{
std::function<void()> actualCallback = [&](){
swiftCallback(swiftClassPtr_, count_, max_);
};
actualCallback();
success = true;
}
#endif
if(!success)
{
UERROR("Failed to call rtabmap::updateProgressionCallback");
@@ -114,8 +140,13 @@ protected:
private:
int count_;
int max_;
#ifdef __ANDROID__
JavaVM *jvm_;
jobject rtabmap_;
#else
void * swiftClassPtr_;
void(*swiftCallback)(void *, int, int);
#endif
};
}

File diff suppressed because it is too large Load Diff

View File

@@ -28,14 +28,15 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#ifndef RTABMAP_APP_H_
#define RTABMAP_APP_H_
#ifdef __ANDROID__
#include <jni.h>
#endif
#include <memory>
#include <tango_client_api.h> // NOLINT
#include <tango-gl/util.h>
#include "scene.h"
#include "CameraTango.h"
#include "CameraMobile.h"
#include "util.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/TextureMesh.h>
// RTABMapApp handles the application lifecycle and resources.
class RTABMapApp : public UEventsHandler {
public:
// Constructor and deconstructor.
#ifdef __ANDROID__
RTABMapApp(JNIEnv* env, jobject caller_activity);
#else // __APPLE__
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();
void onCreate(JNIEnv* env, jobject caller_activity);
void setScreenRotation(int displayRotation, int cameraRotation);
int openDatabase(const std::string & databasePath, bool databaseInMemory, bool optimize, const std::string & databaseSource=std::string());
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);
int openDatabase(const std::string & databasePath, bool databaseInMemory, bool optimize, bool clearDatabase);
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.
void InitializeGLContent();
@@ -92,8 +92,7 @@ class RTABMapApp : public UEventsHandler {
// Main render loop.
int Render();
// Release all non-OpenGL allocated resources.
void onPause();
void stopCamera();
// 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 setFullResolution(bool enabled);
void setSmoothing(bool enabled);
void setDepthFromMotion(bool enabled);
void setAppendMode(bool enabled);
void setDataRecorderMode(bool enabled);
void setMaxCloudDepth(float value);
void setMinCloudDepth(float value);
void setCloudDensityLevel(int value);
void setMeshAngleTolerance(float value);
void setMeshDecimationFactor(float value);
void setMeshTriangleSize(int value);
void setClusterRatio(float value);
void setMaxGainRadius(float value);
void setRenderingTextureDecimation(int value);
void setBackgroundColor(float gray);
void setDepthConfidence(int value);
int setMappingParameter(const std::string & key, const std::string & value);
void setGPS(const rtabmap::GPS & gps);
void addEnvSensor(int type, float value);
void resetMapping();
void save(const std::string & databasePath);
bool recover(const std::string & from, const std::string & to);
void cancelProcessing();
bool exportMesh(
float cloudVoxelSize,
@@ -173,21 +176,42 @@ class RTABMapApp : public UEventsHandler {
bool writeExportedMesh(const std::string & directory, const std::string & name);
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:
virtual bool handleEvent(UEvent * event);
private:
int updateMeshDecimation(int width, int height);
rtabmap::ParametersMap getRtabmapParameters();
bool smoothMesh(int id, Mesh & mesh);
bool smoothMesh(int id, rtabmap::Mesh & mesh);
void gainCompensation(bool full = false);
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;
private:
rtabmap::CameraTango * camera_;
int cameraDriver_;
rtabmap::CameraMobile * camera_;
rtabmap::RtabmapThread * rtabmapThread_;
rtabmap::Rtabmap * rtabmap_;
LogHandler * logHandler_;
rtabmap::LogHandler * logHandler_;
bool odomCloudShown_;
bool graphOptimization_;
@@ -196,6 +220,7 @@ class RTABMapApp : public UEventsHandler {
bool trajectoryMode_;
bool rawScanSaved_;
bool smoothing_;
bool depthFromMotion_;
bool cameraColor_;
bool fullResolution_;
bool appendMode_;
@@ -204,14 +229,15 @@ class RTABMapApp : public UEventsHandler {
int cloudDensityLevel_;
int meshTrianglePix_;
float meshAngleToleranceDeg_;
float meshDecimationFactor_;
float clusterRatio_;
float maxGainRadius_;
int renderingTextureDecimation_;
float backgroundColor_;
int depthConfidence_;
rtabmap::ParametersMap mappingParameters_;
bool paused_;
bool dataRecorderMode_;
bool clearSceneOnNextRender_;
bool openingDatabase_;
@@ -222,7 +248,6 @@ class RTABMapApp : public UEventsHandler {
bool bilateralFilteringOnNextRender_;
bool takeScreenshotOnNextRender_;
bool cameraJustInitialized_;
int meshDecimation_;
int totalPoints_;
int totalPolygons_;
int lastDrawnCloudsCount_;
@@ -241,16 +266,18 @@ class RTABMapApp : public UEventsHandler {
// main_scene_ includes all drawable object for visualizing Tango device's
// movement and point cloud.
Scene main_scene_;
UTimer fpsTime_;
std::list<rtabmap::RtabmapEvent*> rtabmapEvents_;
std::list<rtabmap::RtabmapEvent*> visLocalizationEvents_;
std::list<rtabmap::OdometryEvent> odomEvents_;
std::list<rtabmap::Transform> poseEvents_;
std::map<double, rtabmap::Transform> poseBuffer_;
rtabmap::Transform mapToOdom_;
boost::mutex cameraMutex_;
boost::mutex rtabmapMutex_;
boost::mutex visLocalizationMutex_;
boost::mutex meshesMutex_;
boost::mutex odomMutex_;
boost::mutex poseMutex_;
@@ -258,12 +285,29 @@ class RTABMapApp : public UEventsHandler {
USemaphore screenshotReady_;
std::map<int, Mesh> createdMeshes_;
std::map<int, rtabmap::Mesh> createdMeshes_;
std::map<int, rtabmap::Transform> rawPoses_;
std::pair<rtabmap::RtabmapEventInit::Status, std::string> status_;
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_

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");
}

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_

View File

@@ -31,7 +31,11 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include "rtabmap/utilite/ULogger.h"
#include "util.h"
#ifdef __ANDROID__
#include <GLES2/gl2.h>
#else //__APPLE__
#include <OpenGLES/ES2/gl.h>
#endif
GraphDrawable::GraphDrawable(
GLuint shaderProgram,

View File

@@ -28,8 +28,9 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#ifndef GRAPH_DRAWABLE_H_
#define GRAPH_DRAWABLE_H_
#ifdef __ANDROID__
#include <jni.h>
#endif
#include <tango-gl/util.h>
#include <vector>
#include <pcl/point_cloud.h>

File diff suppressed because it is too large Load Diff

View File

@@ -35,7 +35,11 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include "util.h"
#include "pcl/common/transforms.h"
#ifdef __ANDROID__
#include <GLES2/gl2.h>
#else // __APPLE__
#include <OpenGLES/ES2/gl.h>
#endif
#define LOW_DEC 2
#define LOWLOW_DEC 4
@@ -57,7 +61,7 @@ enum PointCloudShaders
// PointCloud shaders
const std::string kPointCloudVertexShader =
"precision mediump float;\n"
"precision highp float;\n"
"precision mediump int;\n"
"attribute vec3 aVertex;\n"
"attribute vec3 aColor;\n"
@@ -75,7 +79,7 @@ const std::string kPointCloudVertexShader =
" vColor = aColor;\n"
"}\n";
const std::string kPointCloudLightingVertexShader =
"precision mediump float;\n"
"precision highp float;\n"
"precision mediump int;\n"
"attribute vec3 aVertex;\n"
"attribute vec3 aNormal;\n"
@@ -100,7 +104,7 @@ const std::string kPointCloudLightingVertexShader =
"}\n";
const std::string kPointCloudFragmentShader =
"precision mediump float;\n"
"precision highp float;\n"
"precision mediump int;\n"
"uniform float uGainR;\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"
" float alpha = 1.0;\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 diff = (uFarZ - uNearZ);\n"
" float add = (uFarZ + uNearZ);\n"
@@ -141,7 +146,7 @@ const std::string kPointCloudBlendingFragmentShader =
"}\n";
const std::string kPointCloudDepthPackingVertexShader =
"precision mediump float;\n"
"precision highp float;\n"
"precision mediump int;\n"
"attribute vec3 aVertex;\n"
"uniform mat4 uMVP;\n"
@@ -154,15 +159,15 @@ const std::string kPointCloudDepthPackingFragmentShader =
"precision highp float;\n"
"precision mediump int;\n"
"void main() {\n"
" float toFixed = 255.0/256.0;\n"
" vec4 enc = vec4(1.0, 255.0, 65025.0, 160581375.0) * toFixed * gl_FragCoord.z;\n"
" vec4 enc = vec4(1.,255.,65025.,16581375.) * gl_FragCoord.z;\n"
" enc = fract(enc);\n"
" enc -= enc.yzww * vec2(1./255., 0.).xxxy;\n"
" gl_FragColor = enc;\n"
"}\n";
// Texture shaders
const std::string kTextureMeshVertexShader =
"precision mediump float;\n"
"precision highp float;\n"
"precision mediump int;\n"
"attribute vec3 aVertex;\n"
"attribute vec2 aTexCoord;\n"
@@ -185,7 +190,7 @@ const std::string kTextureMeshVertexShader =
" vLightWeighting = 1.0;\n"
"}\n";
const std::string kTextureMeshLightingVertexShader =
"precision mediump float;\n"
"precision highp float;\n"
"precision mediump int;\n"
"attribute vec3 aVertex;\n"
"attribute vec3 aNormal;\n"
@@ -214,7 +219,7 @@ const std::string kTextureMeshLightingVertexShader =
" vLightWeighting=0.5;\n"
"}\n";
const std::string kTextureMeshFragmentShader =
"precision mediump float;\n"
"precision highp float;\n"
"precision mediump int;\n"
"uniform sampler2D uTexture;\n"
"uniform float uGainR;\n"
@@ -245,7 +250,8 @@ const std::string kTextureMeshBlendingFragmentShader =
" vec4 textureColor = texture2D(uTexture, vTexCoord);\n"
" float alpha = 1.0;\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 diff = (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
" if(linearFragz > linearDepth + 0.05)\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";
std::vector<GLuint> PointCloudDrawable::shaderPrograms_;
@@ -303,8 +309,8 @@ PointCloudDrawable::PointCloudDrawable(
float gainR,
float gainG,
float gainB) :
vertex_buffers_(0),
textures_(0),
vertex_buffer_(0),
texture_(0),
nPoints_(0),
pose_(rtabmap::Transform::getIdentity()),
poseGl_(1.0f),
@@ -314,14 +320,16 @@ PointCloudDrawable::PointCloudDrawable(
gainG_(gainG),
gainB_(gainB)
{
index_buffers_.resize(6, 0);
index_buffers_count_.resize(6, 0);
updateCloud(cloud, indices);
}
PointCloudDrawable::PointCloudDrawable(
const Mesh & mesh,
const rtabmap::Mesh & mesh,
bool createWireframe) :
vertex_buffers_(0),
textures_(0),
vertex_buffer_(0),
texture_(0),
nPoints_(0),
pose_(rtabmap::Transform::getIdentity()),
poseGl_(1.0f),
@@ -331,64 +339,83 @@ PointCloudDrawable::PointCloudDrawable(
gainG_(1.0f),
gainB_(1.0f)
{
index_buffers_.resize(6, 0);
index_buffers_count_.resize(6, 0);
updateMesh(mesh, createWireframe);
}
PointCloudDrawable::~PointCloudDrawable()
{
LOGI("Freeing cloud buffer %d", vertex_buffers_);
if (vertex_buffers_)
LOGI("Freeing cloud buffer %d", vertex_buffer_);
if (vertex_buffer_)
{
glDeleteBuffers(1, &vertex_buffers_);
glDeleteBuffers(1, &vertex_buffer_);
tango_gl::util::CheckGlError("PointCloudDrawable::~PointCloudDrawable()");
vertex_buffers_ = 0;
vertex_buffer_ = 0;
}
if (textures_)
if (texture_)
{
glDeleteTextures(1, &textures_);
glDeleteTextures(1, &texture_);
tango_gl::util::CheckGlError("PointCloudDrawable::~PointCloudDrawable()");
textures_ = 0;
texture_ = 0;
}
for(size_t i=0; i<index_buffers_.size(); ++i)
{
if(index_buffers_[i])
{
glDeleteBuffers(1, &index_buffers_[i]);
index_buffers_[i] = 0;
tango_gl::util::CheckGlError("PointCloudDrawable::~PointCloudDrawable()");
}
}
}
void PointCloudDrawable::updatePolygons(const std::vector<pcl::Vertices> & polygons, const std::vector<pcl::Vertices> & polygonsLowRes, bool createWireframe)
{
LOGD("Update polygons");
polygons_.clear();
polygonLines_.clear();
polygonsLowRes_.clear();
polygonLinesLowRes_.clear();
for(int i=0; i<4; ++i)
{
if(index_buffers_[i])
{
glDeleteBuffers(1, &index_buffers_[i]);
index_buffers_[i] = 0;
tango_gl::util::CheckGlError("PointCloudDrawable::updatePolygons() clearing polygon buffers");
}
}
//LOGD("Update polygons");
if(polygons.size() && organizedToDenseIndices_.size())
{
unsigned int polygonSize = polygons[0].vertices.size();
size_t polygonSize = polygons[0].vertices.size();
UASSERT(polygonSize == 3);
polygons_.resize(polygons.size() * polygonSize);
std::vector<std::vector<GLuint> > indexes(4);
indexes[0].resize(polygons.size() * polygonSize);
if(createWireframe)
polygonLines_.resize(polygons_.size()*2);
indexes[2].resize(indexes[0].size()*2);
int oi = 0;
int li = 0;
for(unsigned int i=0; i<polygons.size(); ++i)
for(size_t i=0; i<polygons.size(); ++i)
{
UASSERT(polygons[i].vertices.size() == polygonSize);
for(unsigned int j=0; j<polygonSize; ++j)
{
polygons_[oi++] = organizedToDenseIndices_.at(polygons[i].vertices[j]);
indexes[0][oi++] = organizedToDenseIndices_.at(polygons[i].vertices[j]);
if(createWireframe)
{
polygonLines_[li++] = organizedToDenseIndices_.at(polygons[i].vertices[j]);
polygonLines_[li++] = organizedToDenseIndices_.at(polygons[i].vertices[(j+1) % polygonSize]);
indexes[2][li++] = organizedToDenseIndices_.at(polygons[i].vertices[j]);
indexes[2][li++] = organizedToDenseIndices_.at(polygons[i].vertices[(j+1) % polygonSize]);
}
}
}
if(polygonsLowRes.size())
{
unsigned int polygonSize = polygonsLowRes[0].vertices.size();
size_t polygonSize = polygonsLowRes[0].vertices.size();
UASSERT(polygonSize == 3);
polygonsLowRes_.resize(polygonsLowRes.size() * polygonSize);
indexes[1].resize(polygonsLowRes.size() * polygonSize);
if(createWireframe)
polygonLinesLowRes_.resize(polygonsLowRes_.size()*2);
indexes[3].resize(indexes[1].size()*2);
int oi = 0;
int li = 0;
for(unsigned int i=0; i<polygonsLowRes.size(); ++i)
@@ -396,15 +423,44 @@ void PointCloudDrawable::updatePolygons(const std::vector<pcl::Vertices> & polyg
UASSERT(polygonsLowRes[i].vertices.size() == polygonSize);
for(unsigned int j=0; j<polygonSize; ++j)
{
polygonsLowRes_[oi++] = organizedToDenseIndices_.at(polygonsLowRes[i].vertices[j]);
indexes[1][oi++] = organizedToDenseIndices_.at(polygonsLowRes[i].vertices[j]);
if(createWireframe)
{
polygonLinesLowRes_[li++] = organizedToDenseIndices_.at(polygonsLowRes[i].vertices[j]);
polygonLinesLowRes_[li++] = organizedToDenseIndices_.at(polygonsLowRes[i].vertices[(j+1)%polygonSize]);
indexes[3][li++] = organizedToDenseIndices_.at(polygonsLowRes[i].vertices[j]);
indexes[3][li++] = organizedToDenseIndices_.at(polygonsLowRes[i].vertices[(j+1)%polygonSize]);
}
}
}
}
// Generate index buffers
for(size_t i=0; i<indexes.size(); ++i)
{
if(!indexes[i].empty())
{
glGenBuffers(1, &index_buffers_[i]);
if(!index_buffers_[i])
{
LOGE("OpenGL: could not generate index buffer %ld\n", i);
return;
}
LOGD("Adding polygon index %ld size=%ld", i, indexes[i].size());
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, index_buffers_[i]);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(uint32_t) * indexes[i].size(), indexes[i].data(), GL_STATIC_DRAW);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
index_buffers_count_[i] = (int)indexes[i].size();
GLint error = glGetError();
if(error != GL_NO_ERROR)
{
LOGE("OpenGL: Could not allocate indexes (0x%x)\n", error);
index_buffers_[i] = 0;
return;
}
}
}
}
}
@@ -412,43 +468,51 @@ void PointCloudDrawable::updateCloud(const pcl::PointCloud<pcl::PointXYZRGB>::Pt
{
UASSERT(cloud.get() && !cloud->empty());
nPoints_ = 0;
polygons_.clear();
polygonsLowRes_.clear();
verticesLowRes_.clear();
verticesLowLowRes_.clear();
aabbMinModel_ = aabbMinWorld_ = pcl::PointXYZ(1000,1000,1000);
aabbMaxModel_ = aabbMaxWorld_ = pcl::PointXYZ(-1000,-1000,-1000);
if (vertex_buffers_)
if (vertex_buffer_)
{
glDeleteBuffers(1, &vertex_buffers_);
tango_gl::util::CheckGlError("PointCloudDrawable::~PointCloudDrawable()");
vertex_buffers_ = 0;
glDeleteBuffers(1, &vertex_buffer_);
tango_gl::util::CheckGlError("PointCloudDrawable::updateCloud() clear vertex buffer");
vertex_buffer_ = 0;
}
if (textures_)
if (texture_)
{
glDeleteTextures(1, &textures_);
tango_gl::util::CheckGlError("PointCloudDrawable::~PointCloudDrawable()");
textures_ = 0;
glDeleteTextures(1, &texture_);
tango_gl::util::CheckGlError("PointCloudDrawable::updateCloud() clear texture buffer");
texture_ = 0;
}
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_);
if(!vertex_buffers_)
glGenBuffers(1, &vertex_buffer_);
if(!vertex_buffer_)
{
LOGE("OpenGL: could not generate vertex buffers\n");
return;
}
LOGI("Creating cloud buffer %d", vertex_buffers_);
LOGI("Creating cloud buffer %d", vertex_buffer_);
std::vector<float> vertices;
int totalPoints = 0;
size_t totalPoints = 0;
std::vector<GLuint> verticesLowRes;
std::vector<GLuint> verticesLowLowRes;
if(indices.get() && indices->size())
{
totalPoints = indices->size();
vertices.resize(indices->size()*4);
verticesLowRes_.resize(cloud->isOrganized()?totalPoints:0);
verticesLowLowRes_.resize(cloud->isOrganized()?totalPoints:0);
verticesLowRes.resize(cloud->isOrganized()?totalPoints:0);
verticesLowLowRes.resize(cloud->isOrganized()?totalPoints:0);
int oi_low = 0;
int oi_lowlow = 0;
for(unsigned int i=0; i<indices->size(); ++i)
@@ -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)
{
verticesLowRes_[oi_low++] = i;
verticesLowRes[oi_low++] = i;
}
if(indices->at(i)%LOWLOW_DEC == 0 && (indices->at(i)/cloud->width) % LOWLOW_DEC == 0)
{
verticesLowLowRes_[oi_lowlow++] = i;
verticesLowLowRes[oi_lowlow++] = i;
}
}
}
verticesLowRes_.resize(oi_low);
verticesLowLowRes_.resize(oi_lowlow);
verticesLowRes.resize(oi_low);
verticesLowLowRes.resize(oi_lowlow);
}
else
{
totalPoints = cloud->size();
vertices.resize(cloud->size()*4);
verticesLowRes_.resize(cloud->isOrganized()?totalPoints:0);
verticesLowLowRes_.resize(cloud->isOrganized()?totalPoints:0);
verticesLowRes.resize(cloud->isOrganized()?totalPoints:0);
verticesLowLowRes.resize(cloud->isOrganized()?totalPoints:0);
int oi_low = 0;
int oi_lowlow = 0;
for(unsigned int i=0; i<cloud->size(); ++i)
@@ -498,19 +562,19 @@ void PointCloudDrawable::updateCloud(const pcl::PointCloud<pcl::PointXYZRGB>::Pt
{
if(i%LOW_DEC == 0 && (i/cloud->width) % LOW_DEC == 0)
{
verticesLowRes_[oi_low++] = i;
verticesLowRes[oi_low++] = i;
}
if(i%LOWLOW_DEC == 0 && (i/cloud->width) % LOWLOW_DEC == 0)
{
verticesLowLowRes_[oi_lowlow++] = i;
verticesLowLowRes[oi_lowlow++] = i;
}
}
}
verticesLowRes_.resize(oi_low);
verticesLowLowRes_.resize(oi_lowlow);
verticesLowRes.resize(oi_low);
verticesLowLowRes.resize(oi_lowlow);
}
glBindBuffer(GL_ARRAY_BUFFER, vertex_buffers_);
glBindBuffer(GL_ARRAY_BUFFER, vertex_buffer_);
glBufferData(GL_ARRAY_BUFFER, sizeof(GLfloat) * (int)vertices.size(), (const void *)vertices.data(), GL_STATIC_DRAW);
glBindBuffer(GL_ARRAY_BUFFER, 0);
@@ -518,26 +582,65 @@ void PointCloudDrawable::updateCloud(const pcl::PointCloud<pcl::PointXYZRGB>::Pt
if(error != GL_NO_ERROR)
{
LOGE("OpenGL: Could not allocate point cloud (0x%x)\n", error);
vertex_buffers_ = 0;
vertex_buffer_ = 0;
return;
}
// 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());
nPoints_ = 0;
aabbMinModel_ = aabbMinWorld_ = pcl::PointXYZ(1000,1000,1000);
aabbMaxModel_ = aabbMaxWorld_ = pcl::PointXYZ(-1000,-1000,-1000);
if (vertex_buffers_)
if (vertex_buffer_)
{
glDeleteBuffers(1, &vertex_buffers_);
tango_gl::util::CheckGlError("PointCloudDrawable::~PointCloudDrawable()");
vertex_buffers_ = 0;
glDeleteBuffers(1, &vertex_buffer_);
tango_gl::util::CheckGlError("PointCloudDrawable::updateMesh() clear vertex buffer");
vertex_buffer_ = 0;
}
for(size_t i=0; i<index_buffers_.size(); ++i)
{
if(index_buffers_[i])
{
glDeleteBuffers(1, &index_buffers_[i]);
index_buffers_[i] = 0;
tango_gl::util::CheckGlError("PointCloudDrawable::updateMesh() clear index buffer");
}
}
gainR_ = mesh.gains[0];
gainG_ = mesh.gains[1];
@@ -546,17 +649,17 @@ void PointCloudDrawable::updateMesh(const Mesh & mesh, bool createWireframe)
bool textureUpdate = false;
if(!mesh.texture.empty() && mesh.texture.type() == CV_8UC3)
{
if (textures_)
if (texture_)
{
glDeleteTextures(1, &textures_);
tango_gl::util::CheckGlError("PointCloudDrawable::~PointCloudDrawable()");
textures_ = 0;
glDeleteTextures(1, &texture_);
tango_gl::util::CheckGlError("PointCloudDrawable::updateMesh() clear texture buffer");
texture_ = 0;
}
textureUpdate = true;
}
glGenBuffers(1, &vertex_buffers_);
if(!vertex_buffers_)
glGenBuffers(1, &vertex_buffer_);
if(!vertex_buffer_)
{
LOGE("OpenGL: could not generate vertex buffers\n");
return;
@@ -564,10 +667,10 @@ void PointCloudDrawable::updateMesh(const Mesh & mesh, bool createWireframe)
if(textureUpdate)
{
glGenTextures(1, &textures_);
if(!textures_)
glGenTextures(1, &texture_);
if(!texture_)
{
vertex_buffers_ = 0;
vertex_buffer_ = 0;
LOGE("OpenGL: could not generate texture buffers\n");
return;
}
@@ -578,18 +681,20 @@ void PointCloudDrawable::updateMesh(const Mesh & mesh, bool createWireframe)
int totalPoints = 0;
std::vector<pcl::Vertices> polygons = mesh.polygons;
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());
if(mesh.cloud->isOrganized()) // assume organized mesh
{
polygonsLowRes = mesh.polygonsLowRes; // only in organized we keep the low res
organizedToDenseIndices_ = std::vector<unsigned int>(mesh.cloud->width*mesh.cloud->height, -1);
totalPoints = mesh.indices->size();
verticesLowRes_.resize(totalPoints);
verticesLowLowRes_.resize(totalPoints);
totalPoints = (int)mesh.indices->size();
std::vector<GLuint> verticesLowRes;
std::vector<GLuint> verticesLowLowRes;
verticesLowRes.resize(totalPoints);
verticesLowLowRes.resize(totalPoints);
int oi_low = 0;
int oi_lowlow = 0;
if(textures_ && polygons.size())
if(texture_ && polygons.size())
{
int items = hasNormals_?9:6;
vertices = std::vector<float>(mesh.indices->size()*items);
@@ -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)
{
verticesLowRes_[oi_low++] = i;
verticesLowRes[oi_low++] = i;
}
if(mesh.indices->at(i)%LOWLOW_DEC == 0 && (mesh.indices->at(i)/mesh.cloud->width) % LOWLOW_DEC == 0)
{
verticesLowLowRes_[oi_lowlow++] = i;
verticesLowLowRes[oi_lowlow++] = i;
}
}
}
@@ -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)
{
verticesLowRes_[oi_low++] = i;
verticesLowRes[oi_low++] = i;
}
if(mesh.indices->at(i)%LOWLOW_DEC == 0 && (mesh.indices->at(i)/mesh.cloud->width) % LOWLOW_DEC == 0)
{
verticesLowLowRes_[oi_lowlow++] = i;
verticesLowLowRes[oi_lowlow++] = i;
}
}
}
verticesLowRes_.resize(oi_low);
verticesLowLowRes_.resize(oi_lowlow);
verticesLowRes.resize(oi_low);
verticesLowLowRes.resize(oi_lowlow);
// vertex index buffers
for(size_t i=4; i<5; ++i)
{
if((i==4 && !verticesLowRes.empty()) ||
(i==5 && !verticesLowLowRes.empty()))
{
glGenBuffers(1, &index_buffers_[i]);
if(!index_buffers_[i])
{
LOGE("OpenGL: could not generate index buffer %ld\n", i);
return;
}
index_buffers_count_[i] = i==4?(int)verticesLowRes.size():(int)verticesLowLowRes.size();
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, index_buffers_[i]);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(uint32_t) * index_buffers_count_[i], i==4?verticesLowRes.data():verticesLowLowRes.data(), GL_STATIC_DRAW);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
GLint error = glGetError();
if(error != GL_NO_ERROR)
{
LOGE("OpenGL: Could not allocate indexes (0x%x)\n", error);
index_buffers_[i] = 0;
return;
}
}
}
}
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)",
// (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
// polygon vertices. Points linked to multiple different texCoords (different textures) should
// be duplicated.
totalPoints = mesh.texCoords.size();
vertices = std::vector<float>(mesh.texCoords.size()*9);
totalPoints = (int)mesh.texCoords.size();
int items = hasNormals_?9:6;
vertices = std::vector<float>(mesh.texCoords.size()*items);
organizedToDenseIndices_ = std::vector<unsigned int>(totalPoints, -1);
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());
int items = hasNormals_?9:6;
unsigned int oi=0;
for(unsigned int i=0; i<polygons.size(); ++i)
{
@@ -737,7 +870,7 @@ void PointCloudDrawable::updateMesh(const Mesh & mesh, bool createWireframe)
}
else
{
totalPoints = mesh.cloud->size();
totalPoints = (int)mesh.cloud->size();
//LOGD("Dense mesh");
int items = hasNormals_?7:4;
organizedToDenseIndices_ = std::vector<unsigned int>(totalPoints, -1);
@@ -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);
glBindBuffer(GL_ARRAY_BUFFER, 0);
@@ -773,11 +906,11 @@ void PointCloudDrawable::updateMesh(const Mesh & mesh, bool createWireframe)
if(error != GL_NO_ERROR)
{
LOGE("OpenGL: Could not allocate point cloud (0x%x)\n", error);
vertex_buffers_ = 0;
vertex_buffer_ = 0;
return;
}
if(textures_ && textureUpdate)
if(texture_ && textureUpdate)
{
//GLint maxTextureSize = 0;
//glGetIntegerv(GL_MAX_TEXTURE_SIZE, &maxTextureSize);
@@ -787,13 +920,13 @@ void PointCloudDrawable::updateMesh(const Mesh & mesh, bool createWireframe)
//LOGW("maxTextureUnits=%d", maxTextureUnits);
// gen texture from image
glBindTexture(GL_TEXTURE_2D, textures_);
glBindTexture(GL_TEXTURE_2D, texture_);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
cv::Mat rgbImage;
cv::cvtColor(mesh.texture, rgbImage, CV_BGR2RGBA);
cv::cvtColor(mesh.texture, rgbImage, cv::COLOR_BGR2RGBA);
glPixelStorei(GL_UNPACK_ALIGNMENT, 4);
//glPixelStorei(GL_UNPACK_ROW_LENGTH, 0);
@@ -805,20 +938,17 @@ void PointCloudDrawable::updateMesh(const Mesh & mesh, bool createWireframe)
if(error != GL_NO_ERROR)
{
LOGE("OpenGL: Could not allocate texture (0x%x)\n", error);
textures_ = 0;
texture_ = 0;
glDeleteBuffers(1, &vertex_buffers_);
vertex_buffers_ = 0;
glDeleteBuffers(1, &vertex_buffer_);
vertex_buffer_ = 0;
return;
}
}
nPoints_ = totalPoints;
if(polygons_.size() != polygons.size())
{
updatePolygons(polygons, polygonsLowRes, createWireframe);
}
updatePolygons(polygons, polygonsLowRes, createWireframe);
if(!pose_.isNull())
{
@@ -880,14 +1010,14 @@ void PointCloudDrawable::Render(
bool packDepthToColorChannel,
bool wireFrame) const
{
if(vertex_buffers_ && nPoints_ && visible_ && !shaderPrograms_.empty())
if(vertex_buffer_ && nPoints_ && visible_ && !shaderPrograms_.empty())
{
if(packDepthToColorChannel || !hasNormals_)
{
lighting = false;
}
if(packDepthToColorChannel || !(meshRendering && textureRendering && textures_))
if(packDepthToColorChannel || !(meshRendering && textureRendering && texture_))
{
textureRendering = false;
}
@@ -990,7 +1120,7 @@ void PointCloudDrawable::Render(
// Texture activate unit 0
glActiveTexture(GL_TEXTURE0);
// Bind the texture to this unit.
glBindTexture(GL_TEXTURE_2D, textures_);
glBindTexture(GL_TEXTURE_2D, texture_);
// Tell the texture uniform sampler to use this texture in the shader by binding to texture unit 0.
GLuint texture_handle = glGetUniformLocation(program, "uTexture");
glUniform1i(texture_handle, 0);
@@ -1006,8 +1136,8 @@ void PointCloudDrawable::Render(
}
tango_gl::util::CheckGlError("Pointcloud::Render() common");
glBindBuffer(GL_ARRAY_BUFFER, vertex_buffers_);
if(textures_)
glBindBuffer(GL_ARRAY_BUFFER, vertex_buffer_);
if(texture_)
{
glVertexAttribPointer(attribute_vertex, 3, GL_FLOAT, GL_FALSE, (hasNormals_?9:6)*sizeof(GLfloat), 0);
if(textureRendering)
@@ -1038,53 +1168,49 @@ void PointCloudDrawable::Render(
tango_gl::util::CheckGlError("Pointcloud::Render() set attribute pointer");
UTimer drawTime;
if(textureRendering)
if((textureRendering || meshRendering) && index_buffers_[0])
{
if(distanceToCameraSqr<16.0f || polygonsLowRes_.empty())
float dist = meshRendering?50.0f:16.0f;
if(distanceToCameraSqr<dist || index_buffers_[1]==0)
{
wireFrame = wireFrame && polygonLines_.size();
wireFrame = wireFrame && index_buffers_[2];
if(wireFrame)
glDrawElements(GL_LINES, polygonLines_.size(), GL_UNSIGNED_INT, polygonLines_.data());
{
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, index_buffers_[2]);
glDrawElements(GL_LINES, index_buffers_count_[2], GL_UNSIGNED_INT, 0);
}
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
{
wireFrame = wireFrame && polygonLinesLowRes_.size();
wireFrame = wireFrame && index_buffers_[3];
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
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();
if(wireFrame)
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());
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, index_buffers_[5]);
glDrawElements(GL_POINTS, index_buffers_count_[5], GL_UNSIGNED_INT, 0);
}
else if(distanceToCameraSqr>150.0f)
{
glDrawElements(GL_POINTS, verticesLowRes_.size(), GL_UNSIGNED_INT, verticesLowRes_.data());
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, index_buffers_[4]);
glDrawElements(GL_POINTS, index_buffers_count_[4], GL_UNSIGNED_INT, 0);
}
else
{
@@ -1100,6 +1226,7 @@ void PointCloudDrawable::Render(
glDisableVertexAttribArray(0);
glBindBuffer(GL_ARRAY_BUFFER, 0);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
glUseProgram(0);
tango_gl::util::CheckGlError("Pointcloud::Render() cleaning");

View File

@@ -28,7 +28,9 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#ifndef TANGO_POINT_CLOUD_POINT_CLOUD_DRAWABLE_H_
#define TANGO_POINT_CLOUD_POINT_CLOUD_DRAWABLE_H_
#ifdef __ANDROID__
#include <jni.h>
#endif
#include <tango-gl/util.h>
#include <vector>
@@ -55,21 +57,21 @@ private:
float gainG = 1.0f,
float gainB = 1.0f);
PointCloudDrawable(
const Mesh & mesh,
const rtabmap::Mesh & mesh,
bool createWireframe = false);
virtual ~PointCloudDrawable();
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 updateMesh(const Mesh & mesh, bool createWireframe = false);
void updateMesh(const rtabmap::Mesh & mesh, bool createWireframe = false);
void setPose(const rtabmap::Transform & pose);
void setVisible(bool visible) {visible_=visible;}
void setGains(float gainR, float gainG, float gainB) {gainR_ = gainR; gainG_ = gainG; gainB_ = gainB;}
rtabmap::Transform getPose() const {return pose_;}
const glm::mat4 & getPoseGl() const {return poseGl_;}
bool isVisible() const {return visible_;}
bool hasMesh() const {return polygons_.size()!=0;}
bool hasTexture() const {return textures_ != 0;}
bool hasMesh() const {return index_buffers_[0] != 0;}
bool hasTexture() const {return texture_ != 0;}
float getMinHeight() const {return minHeight_;}
const pcl::PointXYZ & aabbMinModel() const {return aabbMinModel_;}
const pcl::PointXYZ & aabbMaxModel() const {return aabbMaxModel_;}
@@ -113,14 +115,10 @@ private:
private:
// Vertex buffer of the point cloud geometry.
GLuint vertex_buffers_;
GLuint textures_;
std::vector<GLuint> polygons_;
std::vector<GLuint> polygonsLowRes_;
std::vector<GLuint> polygonLines_;
std::vector<GLuint> polygonLinesLowRes_;
std::vector<GLuint> verticesLowRes_;
std::vector<GLuint> verticesLowLowRes_;
GLuint vertex_buffer_;
GLuint texture_;
std::vector<GLuint> index_buffers_;
std::vector<int> index_buffers_count_;
int nPoints_;
rtabmap::Transform pose_;
glm::mat4 poseGl_;

View File

@@ -69,6 +69,7 @@ const std::string kGraphFragmentShader =
Scene::Scene() :
background_renderer_(0),
gesture_camera_(0),
axis_(0),
frustum_(0),
@@ -79,14 +80,15 @@ Scene::Scene() :
graphVisible_(true),
gridVisible_(true),
traceVisible_(true),
color_camera_to_display_rotation_(ROTATION_0),
frustumVisible_(true),
color_camera_to_display_rotation_(rtabmap::ROTATION_0),
currentPose_(0),
graph_shader_program_(0),
blending_(true),
mapRendering_(true),
meshRendering_(true),
meshRenderingTexture_(true),
pointSize_(5.0f),
pointSize_(10.0f),
boundingBoxRendering_(false),
lighting_(false),
backfaceCulling_(true),
@@ -95,19 +97,21 @@ Scene::Scene() :
g_(0.0f),
b_(0.0f),
fboId_(0),
depthTexture_(0),
rboId_(0),
screenWidth_(0),
screenHeight_(0),
doubleTapOn_(false)
{
depthTexture_ = 0;
gesture_camera_ = new tango_gl::GestureCamera();
gesture_camera_->SetCameraType(
tango_gl::GestureCamera::kFirstPerson);
tango_gl::GestureCamera::kThirdPersonFollow);
}
Scene::~Scene() {
DeleteResources();
delete gesture_camera_;
delete currentPose_;
}
//Should only be called in OpenGL thread!
@@ -126,7 +130,6 @@ void Scene::InitGLContent()
trace_ = new tango_gl::Trace();
grid_ = new tango_gl::Grid();
box_ = new BoundingBoxDrawable();
currentPose_ = new rtabmap::Transform();
axis_->SetScale(glm::vec3(0.5f,0.5f,0.5f));
@@ -158,8 +161,9 @@ void Scene::DeleteResources() {
delete frustum_;
delete trace_;
delete grid_;
delete currentPose_;
delete box_;
delete background_renderer_;
background_renderer_ = 0;
}
PointCloudDrawable::releaseShaderPrograms();
@@ -173,8 +177,10 @@ void Scene::DeleteResources() {
{
glDeleteFramebuffers(1, &fboId_);
fboId_ = 0;
glDeleteTextures(1, &depthTexture_);
depthTexture_ = 0;
glDeleteRenderbuffers(1, &rboId_);
rboId_ = 0;
glDeleteTextures(1, &depthTexture_);
depthTexture_ = 0;
}
clear();
@@ -188,6 +194,10 @@ void Scene::clear()
{
delete iter->second;
}
for(std::map<int, tango_gl::Axis*>::iterator iter=markers_.begin(); iter!=markers_.end(); ++iter)
{
delete iter->second;
}
if(trace_)
{
trace_->ClearVertexArray();
@@ -198,6 +208,7 @@ void Scene::clear()
graph_ = 0;
}
pointClouds_.clear();
markers_.clear();
if(grid_)
{
grid_->SetPosition(kHeightOffset);
@@ -209,19 +220,32 @@ void Scene::SetupViewPort(int w, int h) {
if (h == 0) {
LOGE("Setup graphic height not valid");
}
UASSERT(gesture_camera_ != 0);
gesture_camera_->SetWindowSize(static_cast<float>(w), static_cast<float>(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)
{
glDeleteFramebuffers(1, &fboId_);
fboId_ = 0;
glDeleteRenderbuffers(1, &rboId_);
rboId_ = 0;
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
glGenTextures(1, &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_MAG_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);
glGenRenderbuffers(1, &rboId_);
glBindRenderbuffer(GL_RENDERBUFFER, rboId_);
glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT16, w, h);
glBindRenderbuffer(GL_RENDERBUFFER, 0);
// regenerate fbo texture
// create a framebuffer object, you need to delete them when program exits.
glGenFramebuffers(1, &fboId_);
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);
// Set the texture to be at the color attachment point of the FBO (we pack depth 32 bits in color)
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, depthTexture_, 0);
glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, rboId_);
GLuint status = glCheckFramebufferStatus(GL_FRAMEBUFFER);
if ( status != GL_FRAMEBUFFER_COMPLETE)
{
LOGE("Frame buffer cannot be generated! Status: %in", status);
}
glBindFramebuffer(GL_FRAMEBUFFER,0);
}
UASSERT ( status == GL_FRAMEBUFFER_COMPLETE);
glBindFramebuffer(GL_FRAMEBUFFER, originid);
}
screenWidth_ = w;
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.
* http://www.txutxi.com/?p=584
* @param f Viewing frustum.
* @param b An axis aligned bounding box.
* @param planes Viewing frustum.
* @param boxMin The axis aligned bounding box min.
* @param boxMax The axis aligned bounding box max.
* @return True if b intersects f, false otherwise.
*/
bool intersectFrustumAABB(
@@ -359,9 +382,14 @@ bool intersectFrustumAABB(
}
//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);
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());
Eigen::Quaternionf quat = currentPose_->getQuaternionf();
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 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);
// transform in same coordinate as frustum filtering
openglCamera *= rtabmap::Transform(
@@ -433,28 +480,45 @@ int Scene::Render() {
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_)
{
GLint originid = 0;
glGetIntegerv(GL_FRAMEBUFFER_BINDING, &originid);
// set the rendering destination to FBO
glBindFramebuffer(GL_FRAMEBUFFER, fboId_);
glColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE);
glClearColor(1, 1, 1, 1);
glClearColor(0, 0, 0, 0);
glClear(GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT);
// Draw scene
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
(*iter)->Render(projectionMatrix, viewMatrix, meshRendering_, pointSize_, false, false, 999.0f);
}
// Draw scene
for(std::vector<PointCloudDrawable*>::const_iterator iter=cloudsToDraw.begin(); iter!=cloudsToDraw.end(); ++iter)
{
Eigen::Vector3f cloudToCamera(
(*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
glBindFramebuffer(GL_FRAMEBUFFER, 0); // unbind
glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
glBindFramebuffer(GL_FRAMEBUFFER, originid); // unbind
}
if(doubleTapOn_ && gesture_camera_->GetCameraType() != tango_gl::GestureCamera::kFirstPerson)
@@ -462,16 +526,21 @@ int Scene::Render() {
glClearColor(0, 0, 0, 0);
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)
{
// set large distance to cam to use low res polygons for fast processing
(*iter)->Render(projectionMatrix, viewMatrix, meshRendering_, pointSize_*10.0f, false, false, 999.0f, 0, 0, 0, 0, 0, true);
Eigen::Vector3f cloudToCamera(
(*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];
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)*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;
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;
if(zValueF != 0.0f)
{
@@ -485,10 +554,19 @@ int Scene::Render() {
glClearColor(r_, g_, b_, 1.0f);
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 (gesture_camera_->GetCameraType() != tango_gl::GestureCamera::kFirstPerson)
if (frustumVisible_ && gesture_camera_->GetCameraType() != tango_gl::GestureCamera::kFirstPerson)
{
frustum_->SetPosition(position);
frustum_->SetRotation(rotation);
@@ -497,8 +575,13 @@ int Scene::Render() {
frustum_->SetScale(kFrustumScale);
frustum_->Render(projectionMatrix, viewMatrix);
axis_->SetPosition(position);
axis_->SetRotation(rotation);
rtabmap::Transform cameraFrame = *currentPose_*rtabmap::optical_T_opengl*rtabmap::CameraMobile::opticalRotationInv;
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);
}
@@ -507,11 +590,15 @@ int Scene::Render() {
{
trace_->Render(projectionMatrix, viewMatrix);
}
else
{
trace_->ClearVertexArray();
}
}
if(gridVisible_)
{
grid_->Render(projectionMatrix, viewMatrix);
}
if(gridVisible_ && !renderBackgroundCamera)
{
grid_->Render(projectionMatrix, viewMatrix);
}
if(graphVisible_ && graph_)
@@ -547,9 +634,20 @@ int Scene::Render() {
if(onlineBlending)
{
if(renderBackgroundCamera && meshRendering_)
{
background_renderer_->Draw(uvsTransformed, depthTexture_, screenWidth_, screenHeight_, mapping);
}
glDisable (GL_BLEND);
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();
}
@@ -560,8 +658,11 @@ void Scene::SetCameraType(tango_gl::GestureCamera::CameraType camera_type) {
void Scene::SetCameraPose(const rtabmap::Transform & pose)
{
UASSERT(currentPose_ != 0);
UASSERT(!pose.isNull());
if(currentPose_ ==0)
{
currentPose_ = new rtabmap::Transform(0,0,0,0,0,-M_PI/2.0f);
}
*currentPose_ = pose;
}
@@ -589,7 +690,7 @@ rtabmap::Transform Scene::GetOpenGLCameraPose(float * fov) const
{
*fov = gesture_camera_->getFOV();
}
return glmToTransform(gesture_camera_->GetTransformationMatrix());
return rtabmap::glmToTransform(gesture_camera_->GetTransformationMatrix());
}
void Scene::OnTouchEvent(int touch_count,
@@ -618,18 +719,10 @@ void Scene::updateGraph(
const std::multimap<int, rtabmap::Link> & links)
{
LOGI("updateGraph");
if(graph_)
{
delete graph_;
graph_ = 0;
}
//create
if(graphVisible_)
{
UASSERT(graph_shader_program_ != 0);
graph_ = new GraphDrawable(graph_shader_program_, poses, links);
}
UASSERT(graph_shader_program_ != 0);
delete graph_;
graph_ = new GraphDrawable(graph_shader_program_, poses, links);
}
void Scene::setGraphVisible(bool visible)
@@ -647,7 +740,59 @@ void Scene::setTraceVisible(bool visible)
traceVisible_ = visible;
}
void Scene::setFrustumVisible(bool visible)
{
frustumVisible_ = visible;
}
//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(
int id,
const pcl::PointCloud<pcl::PointXYZRGB>::Ptr & cloud,
@@ -670,7 +815,7 @@ void Scene::addCloud(
void Scene::addMesh(
int id,
const Mesh & mesh,
const rtabmap::Mesh & mesh,
const rtabmap::Transform & pose,
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);
if(iter != pointClouds_.end())

View File

@@ -17,11 +17,13 @@
#ifndef TANGO_POINT_CLOUD_SCENE_H_
#define TANGO_POINT_CLOUD_SCENE_H_
#ifdef __ANDROID__
#include <jni.h>
#endif
#include <memory>
#include <set>
#include <tango_client_api.h> // NOLINT
#include "CameraMobile.h"
#include <tango-gl/axis.h>
#include <tango-gl/camera.h>
#include <tango-gl/color.h>
@@ -35,9 +37,10 @@
#include <rtabmap/core/Transform.h>
#include <rtabmap/core/Link.h>
#include <point_cloud_drawable.h>
#include <graph_drawable.h>
#include <bounding_box_drawable.h>
#include "point_cloud_drawable.h"
#include "graph_drawable.h"
#include "bounding_box_drawable.h"
#include "background_renderer.h"
#include <pcl/point_cloud.h>
#include <pcl/point_types.h>
@@ -60,7 +63,8 @@ class Scene {
int getViewPortWidth() const {return screenWidth_;}
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
@@ -70,15 +74,16 @@ class Scene {
// frame's timestamp.
// @param: point_cloud_vertices, point cloud's vertices of the current point
// 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.
//
// @param: camera_type, camera type includes first person, third person and
// top down
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 GetOpenGLCameraPose(float * fov = 0) const;
@@ -101,6 +106,13 @@ class Scene {
void setGraphVisible(bool visible);
void setGridVisible(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(
int id,
@@ -109,7 +121,7 @@ class Scene {
const rtabmap::Transform & pose);
void addMesh(
int id,
const Mesh & mesh,
const rtabmap::Mesh & mesh,
const rtabmap::Transform & pose,
bool createWireframe = false);
@@ -120,7 +132,7 @@ class Scene {
bool hasTexture(int id) const;
std::set<int> getAddedClouds() const;
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 setBlending(bool enabled) {blending_ = enabled;}
@@ -143,6 +155,9 @@ class Scene {
float getPointSize() const {return pointSize_;}
bool isLighting() const {return lighting_;}
bool isBackfaceCulling() const {return backfaceCulling_;}
bool isWireframe() const {return wireFrame_;}
BackgroundRenderer * background_renderer_;
private:
// Camera object that allows user to use touch input to interact with.
@@ -166,8 +181,11 @@ class Scene {
bool graphVisible_;
bool gridVisible_;
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_;
@@ -189,7 +207,8 @@ class Scene {
float g_;
float b_;
GLuint fboId_;
GLuint depthTexture_;
GLuint rboId_;
GLuint depthTexture_; // 0=objects+occlusion
GLsizei screenWidth_;
GLsizei screenHeight_;
bool doubleTapOn_;

View File

@@ -24,8 +24,8 @@ Camera::Camera() {
aspect_ratio_ = 4.0f / 3.0f;
width_ = 800.0f;
height_ = 600.0f;
near_clip_plane_ = 0.2f;
far_clip_plane_ = 1000.0f;
near_clip_plane_ = 0.5f;
far_clip_plane_ = 50.0f;
ortho_ = false;
orthoScale_ = 2.0f;
orthoCropFactor_ = -1.0f;

View File

@@ -18,11 +18,14 @@
namespace tango_gl {
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,
1.0f, -1.0f, 0.0f, 0.0f, 0.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};
0.0f, 0.0f, 0.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, -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};
Frustum::Frustum() : Line(3.0f, GL_LINES) {
SetShader();

View File

@@ -43,9 +43,11 @@ const float kCamViewMaxDist = 100.f;
// FOV set up values.
// Third and top down camera's FOV is 65 degrees.
// First person camera's FOV is 45 degrees.
const float kHighFov = 65.0f;
// First person camera's FOV is 85 degrees.
const float kHighestFov = 120.0f;
const float kHighFov = 85.0f;
const float kLowFov = 65.0f;
const float kLowestFov = 40.0f;
}
namespace tango_gl {
@@ -111,7 +113,7 @@ void GestureCamera::OnTouchEvent(int touch_count, TouchEvent event, float x0,
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
{
@@ -179,8 +181,9 @@ void GestureCamera::SetCameraType(CameraType camera_index) {
camera_type_ = camera_index;
switch (camera_index) {
case kFirstPerson:
SetOrthoMode(false);
SetFieldOfView(kLowFov);
SetOrthoMode(false);
SetFieldOfView(kLowestFov);
SetNearFarClipPlanes(0.25, 25);
SetPosition(glm::vec3(0.0f, 0.0f, 0.0f));
SetRotation(glm::quat(1.0f, 0.0f, 0.0f, 0.0f));
cam_cur_dist_ = 0.0f;
@@ -193,14 +196,15 @@ void GestureCamera::SetCameraType(CameraType camera_index) {
break;
case kThirdPerson:
case kThirdPersonFollow:
SetOrthoMode(false);
SetFieldOfView(kHighFov);
SetOrthoMode(false);
SetFieldOfView(kLowFov);
SetNearFarClipPlanes(1, 50);
SetPosition(glm::vec3(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);
cam_cur_angle_.x = -M_PI / 6.0f;
cam_cur_angle_.y = kThirdPersonFollow?0:M_PI / 4.0f;
cam_cur_angle_.x = -M_PI / 12.0f;
cam_cur_angle_.y = kThirdPersonFollow?0:M_PI / 2.0f;
cam_cur_target_rot_ = glm::quat(1,0,0,0);
StartCameraToCurrentTransform();
break;
@@ -208,7 +212,8 @@ void GestureCamera::SetCameraType(CameraType camera_index) {
SetPosition(glm::vec3(0.0f, 0.0f, 0.0f));
SetRotation(glm::quat(1.0f, 0.0f, 0.0f, 0.0f));
SetOrthoMode(false);
SetFieldOfView(kHighFov);
SetFieldOfView(kLowFov);
SetNearFarClipPlanes(1, 50);
cam_cur_dist_ = kTopDownCameraDist;
anchor_offset_ = glm::vec3(0.0f,0.0f,0.0f);
cam_cur_angle_.x = -M_PI / 2.0f;
@@ -222,6 +227,8 @@ void GestureCamera::SetCameraType(CameraType camera_index) {
SetOrthoMode(true);
SetOrthoScale(kTopDownCameraDist);
SetOrthoCropFactor(-1.0f);
SetFieldOfView(kLowFov);
SetNearFarClipPlanes(1, 50);
cam_cur_dist_ = kTopDownCameraDist;
anchor_offset_ = glm::vec3(0.0f,0.0f,0.0f);
cam_cur_angle_.x = -M_PI / 2.0f;

View File

@@ -31,13 +31,17 @@ Grid::Grid(float density, int qx, int qy) : Line(1.0f, GL_LINES) {
// Horizontal line.
for (int i = 0; i < (qy + 1); i++) {
vec_vertices_.push_back(glm::vec3(-width, 0.0f, -height + i * density));
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 + 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++) {
vec_vertices_.push_back(glm::vec3(-width + i * density, 0.0f, -height));
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 + j*density));
vec_vertices_.push_back(glm::vec3(-width + i * density, 0.0f, -height + (j+1)*density));
}
}
}
} // namespace tango_gl

View File

@@ -18,7 +18,10 @@
#define TANGO_GL_TEXTURE_H_
#include <errno.h>
#ifdef __ANDROID__
#include <png.h>
#endif
#include "tango-gl/util.h"
@@ -30,11 +33,15 @@ class Texture {
Texture& operator=(const Texture&) = delete;
~Texture();
#ifdef __ANDROID__
bool LoadFromPNG(const char* file_path);
#endif
GLuint GetTextureID() const;
private:
#ifdef __ANDROID__
png_uint_32 width_, height_;
#endif
int bit_depth_, color_type_;
char* byte_data_;
GLuint texture_id_;

View File

@@ -21,11 +21,16 @@
#define GL_VERTEX_PROGRAM_POINT_SIZE 0x8642
#include <stdlib.h>
#ifdef __ANDROID__
#include <jni.h>
#include <android/log.h>
#include <GLES2/gl2.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/gtc/matrix_transform.hpp"
@@ -34,16 +39,28 @@
#include "glm/gtx/matrix_decompose.hpp"
#define LOG_TAG "rtabmap"
#ifdef DISABLE_LOG
#if defined(DISABLE_LOG)
#define LOGD(...) ;
#define LOGI(...) ;
#define LOGW(...) ;
#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 LOGI(...) __android_log_print(ANDROID_LOG_INFO,LOG_TAG,__VA_ARGS__)
#define LOGW(...) __android_log_print(ANDROID_LOG_WARN,LOG_TAG,__VA_ARGS__)
#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 LOGF(...) __android_log_print(ANDROID_LOG_FATAL,LOG_TAG,__VA_ARGS__)
#endif
#ifndef M_PI
#define M_PI 3.1415926f
@@ -84,32 +101,6 @@ namespace util {
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 tango_gl
#endif // TANGO_GL_RENDERER_GL_UTIL

View File

@@ -57,7 +57,7 @@ Quad::Quad() {
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,
const glm::mat4& view_mat) const {

View File

@@ -34,11 +34,13 @@ static int RoundUpPowerOfTwo(int w) {
}
Texture::Texture(const char* file_path) {
#ifdef __ANDROID__
if (!LoadFromPNG(file_path)) {
LOGE("Texture initialing error");
}
#endif
}
#ifdef __ANDROID__
bool Texture::LoadFromPNG(const char* file_path) {
FILE* file = fopen(file_path, "rb");
@@ -94,7 +96,7 @@ bool Texture::LoadFromPNG(const char* file_path) {
return true;
}
#endif
GLuint Texture::GetTextureID() const { return texture_id_; }
Texture::~Texture() {

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));
}
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

View File

@@ -28,8 +28,6 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#ifndef UTIL_H_
#define UTIL_H_
#include <android/log.h>
#include <rtabmap/utilite/UEventsHandler.h>
#include <rtabmap/utilite/ULogger.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/pcl_base.h>
namespace rtabmap {
class LogHandler : public UEventsHandler
{
public:
LogHandler()
{
ULogger::setLevel(ULogger::kDebug);
ULogger::setEventLevel(ULogger::kDebug);
#ifdef DISABLE_LOG
ULogger::setLevel(ULogger::kWarning);
ULogger::setEventLevel(ULogger::kWarning);
#else
ULogger::setLevel(ULogger::kDebug);
ULogger::setEventLevel(ULogger::kDebug);
#endif
ULogger::setPrintThreadId(true);
registerToEventsManager();
@@ -53,31 +58,39 @@ public:
protected:
virtual bool handleEvent(UEvent * event)
{
if(event->getClassName().compare("ULogEvent") == 0)
if(event->getClassName().compare("ULogEvent") == 0)
{
ULogEvent * logEvent = (ULogEvent*)event;
if(logEvent->getCode() == ULogger::kDebug)
{
LOGD(logEvent->getMsg().c_str());
LOGD("%s", logEvent->getMsg().c_str());
}
else if(logEvent->getCode() == ULogger::kInfo)
{
LOGI(logEvent->getMsg().c_str());
LOGI("%s", logEvent->getMsg().c_str());
}
else if(logEvent->getCode() == ULogger::kWarning)
{
LOGW(logEvent->getMsg().c_str());
LOGW("%s", logEvent->getMsg().c_str());
}
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;
}
};
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(
1.0f, 0.0f, 0.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,
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, 0.0f, 1.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(
0.0f, -1.0f, 0.0f, 0.0f,
0.0f, 0.0f, 1.0f, 0.0f,
-1.0f, 0.0f, 0.0f, 0.0f);
static const rtabmap::Transform rtabmap_device_T_opengl_device(
0.0f, 0.0f, -1.0f, 0.0f,
-1.0f, 0.0f, 0.0f, 0.0f,
0.0f, 1.0f, 0.0f, 0.0f);
static const rtabmap::Transform rtabmap_world_T_opengl_world(
0.0f, 0.0f,-1.0f, 0.0f,
-1.0f, 0.0f, 0.0f, 0.0f,
0.0f, 1.0f, 0.0f, 0.0f);
inline glm::mat4 glmFromTransform(const rtabmap::Transform & transform)
{
@@ -173,4 +191,81 @@ public:
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_ */

1
app/android/libs/.gitignore vendored Normal file
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

View File

@@ -27,6 +27,26 @@
android:layout_width="wrap_content"
android:layout_height="match_parent"
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
android:id="@+id/wireframe_button"
@@ -80,16 +100,6 @@
android:text="@string/camera_button"
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
android:id="@+id/button_shareToSketchfab"
@@ -138,7 +148,23 @@
android:paddingBottom="10dp"
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>

View File

@@ -1,5 +1,13 @@
<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
android:title="@string/pref_title_rendering">
<ListPreference
@@ -78,7 +86,7 @@
android:title="@string/pref_title_mapping_sub"
android:summary="@string/pref_summary_mapping"
android:persistent="false">
<com.introlab.rtabmap.CustomSwitchPreference
android:key="@string/pref_key_append"
android:title="@string/pref_title_append"
@@ -90,6 +98,18 @@
android:summary="@string/pref_summary_resolution"
android:defaultValue="@string/pref_default_resolution"/>
<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:title="@string/pref_title_smoothing"
android:summary="@string/pref_summary_smoothing"
@@ -191,6 +211,20 @@
android:title="@string/pref_title_optimize_end"
android:summary="@string/pref_summary_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
android:title="@string/pref_title_mapping_database">
@@ -209,6 +243,11 @@
android:title="@string/pref_title_gps_saved"
android:summary="@string/pref_summary_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
android:key="@string/pref_key_db_in_memory"
android:title="@string/pref_title_db_in_memory"

View File

@@ -62,20 +62,11 @@
android:checked="true"
android:text="Draft Mode" />
<LinearLayout
<Button
android:id="@+id/button_ok"
android:layout_width="match_parent"
android:layout_height="0dip"
android:layout_weight="1"
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>
android:layout_height="wrap_content"
android:text="Upload" />
</LinearLayout>
</ScrollView>

View File

@@ -7,26 +7,12 @@
<item android:id="@+id/mesh" android:title="Mesh" />
<item android:id="@+id/texture_mesh" android:checked="true" android:title="Texture Mesh" />
</group>
<item android:id="@+id/save" android:title="Save" android:showAsAction="ifRoom"/>
<item android:id="@+id/export" android:showAsAction="ifRoom" android:title="Export">
<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/new_scan" android:title="New Scan"/>
<item android:id="@+id/open" android:title="Library" android:showAsAction="ifRoom"/>
<item android:id="@+id/save" android:title="Save"/>
<item android:id="@+id/post_processing" android:title="Optimize" android:showAsAction="ifRoom">
<item android:id="@+id/post_processing" android:title="Optimize">
<menu>
<item android:id="@+id/post_processing_standard" android:title="Standard Optimization" />
<item android:id="@+id/post_processing_advanced" android:title="Advanced..." >
@@ -43,7 +29,22 @@
</menu>
</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...">
<menu >
@@ -68,7 +69,7 @@
</menu>
</item>
<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"/>
</group>
</menu>

View File

@@ -1,4 +1,3 @@
<resources>
<dimen name="image_width">150dp</dimen>
</resources>
<resources>
<dimen name="image_width">150dp</dimen>
</resources>

View File

@@ -9,15 +9,17 @@
<string name="status">"Status: "</string>
<string name="words">"Words: "</string>
<string name="camera_button">First View</string>
<string name="pause">Pause</string>
<string name="resume">Resume</string>
<string name="library">Library</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_off">Backface</string>
<string name="light_on">Lighting</string>
<string name="light_off">Lighting</string>
<string name="wireframe">Wireframe</string>
<string name="close_visualization">Close Visualization</string>
<string name="save_to_file">Export to File&#8230;</string>
<string name="save_to_file">Export OBJ/PLY&#8230;</string>
<string name="share_to_sketchfab">Share to Sketchfab&#8230;</string>
<string name="start">Start</string>
<string name="nodes">"Nodes (WM): "</string>
@@ -36,6 +38,7 @@
<string name="fps">"FPS (rendering): "</string>
<string name="distance">"Distance travelled: "</string>
<string name="gps">"GPS (long,lat,alt,bearing,err): "</string>
<string name="env_sensors">"Sensors: "</string>
<string name="time">"Time: "</string>
<!-- Preference keys: BEGIN -->
@@ -48,7 +51,7 @@
<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_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_default_min_depth">0</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_default_resolution">false</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_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_default_update_rate">1</string>
<string name="pref_key_max_speed">pref_key_max_speed</string>
<string name="pref_default_max_speed">0</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_default_mem_thr">0</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_default_min_inliers">25</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_default_features_voc">200</string>
<string name="pref_key_features">pref_key_features</string>
@@ -102,12 +111,18 @@
<string name="pref_default_optimizer">2</string>
<string name="pref_key_optimize_end">pref_key_optimize_end</string>
<string name="pref_default_optimize_end">true</string>
<string name="pref_key_marker_detection">pref_key_marker_detection</string>
<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_default_keep_all_db">true</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_key_gps_saved">pref_key_gps_saved</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_default_db_in_memory">false</string>
@@ -149,7 +164,7 @@
<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_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_summary_min_depth">Points under the minimum depth are not rendered.</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_title_mapping_core">Core</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_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>
@@ -344,15 +365,35 @@
<string name="pref_summary_optimizer">Graph optimization approach.</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_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_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_summary_raw_scan_saved">Save raw point clouds in database.</string>
<string name="pref_title_gps_saved">Save GPS</string>
<string name="pref_summary_gps_saved">Save GPS in database.</string>
<string name="pref_title_db_in_memory">Database In Memory</string>
<string name="pref_summary_gps_saved">Save GPS to database.</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-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">
<item>"Max"</item>
<item>"5 Hz"</item>
@@ -371,6 +412,24 @@
<item>"1"</item>
<item>"0.5"</item>
</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">
<item>"No Limit"</item>
<item>"High"</item>
@@ -398,7 +457,7 @@
<item>"700 ms"</item>
<item>"600 ms"</item>
<item>"500 ms"</item>
<item>"400"</item>
<item>"400 ms"</item>
</string-array>
<string-array name="pref_time_thr_values">
<item>"0"</item>
@@ -494,29 +553,25 @@
<item>"10"</item>
</string-array>
<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>"3.5x"</item>
<item>"3x"</item>
<item>"2.5x"</item>
<item>"2x"</item>
<item>"1.5x"</item>
<item>"1x"</item>
<item>"0.5x"</item>
<item>"Disabled"</item>
</string-array>
<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>"3.5"</item>
<item>"3"</item>
<item>"2.5"</item>
<item>"2"</item>
<item>"1.5"</item>
<item>"1"</item>
<item>"0.5"</item>
<item>"0"</item>
</string-array>
<string-array name="pref_features_voc_keys">
@@ -591,10 +646,95 @@
<item>"1"</item>
<item>"0"</item>
</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">Exporting</string>
<string name="pref_summary_export">Advanced parameters used when exporting the map.</string>
<string name="pref_title_export_sub">Assembling&#8230;</string>
<string name="pref_title_export">Assembling</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_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>
@@ -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_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_title_block_render">Block Rendering Thread While Exporting</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_title_block_render">Block Rendering Thread While Assembling</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">
<item>"0.2 m"</item>
@@ -714,7 +854,7 @@
<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_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_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>
@@ -748,10 +888,10 @@
<item>"0.2 m"</item>
<item>"0.1 m"</item>
<item>"0.05 m"</item>
<item>"0.025"</item>
<item>"0.02"</item>
<item>"0.015"</item>
<item>"0.01"</item>
<item>"0.025 m"</item>
<item>"0.02 m"</item>
<item>"0.015 m"</item>
<item>"0.01 m"</item>
<item>"Disabled"</item>
</string-array>
<string-array name="pref_opt_color_radius_values">

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>

View File

@@ -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;
}
}

View File

@@ -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;
}
}

View File

@@ -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

View File

@@ -1,5 +1,10 @@
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.view.KeyEvent;
import android.util.Log;
@@ -15,7 +20,7 @@ public class RTABMapLib
// the correct library first.
if (TangoInitializationHelper.loadTangoSharedLibrary() ==
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");
}
@@ -23,87 +28,86 @@ public class RTABMapLib
// Initialize the Tango Service, this function starts the communication
// between the application and Tango Service.
// 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 int openDatabase2(String databaseSource, String databasePath, boolean databaseInMemory, boolean optimize);
public static native void setScreenRotation(long nativeApplication, int displayRotation, int cameraRotation);
/*
* Called when the Tango service is connected.
*
* @param binder The native binder object.
*/
public static native boolean onTangoServiceConnected(IBinder binder);
public static native int openDatabase(long nativeApplication, String databasePath, boolean databaseInMemory, boolean optimize, boolean clearDatabase);
public static native boolean recover(long nativeApplication, String from, String to);
// Release all non OpenGl resources that are allocated from the program.
public static native void onPause();
public static native boolean isBuiltWith(long nativeApplication, int cameraDriver);
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.
public static native void initGlContent();
public static native void initGlContent(long nativeApplication);
// 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.
public static native int render();
public static native int render(long nativeApplication);
// Set the render camera's viewing angle:
// 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.
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);
public static native void setPausedMapping(boolean paused);
public static native void setOnlineBlending(boolean enabled);
public static native void setMapCloudShown(boolean shown);
public static native void setOdomCloudShown(boolean shown);
public static native void setMeshRendering(boolean enabled, boolean withTexture);
public static native void setLocalizationMode(boolean enabled);
public static native void setTrajectoryMode(boolean enabled);
public static native void setGraphOptimization(boolean enabled);
public static native void setNodesFiltering(boolean enabled);
public static native void setGraphVisible(boolean visible);
public static native void setGridVisible(boolean visible);
public static native void setRawScanSaved(boolean enabled);
public static native void setFullResolution(boolean enabled);
public static native void setSmoothing(boolean enabled);
public static native void setCameraColor(boolean enabled);
public static native void setAppendMode(boolean enabled);
public static native void setDataRecorderMode(boolean enabled);
public static native void setMaxCloudDepth(float value);
public static native void setMinCloudDepth(float value);
public static native void setPointSize(float value);
public static native void setFOV(float value);
public static native void setOrthoCropFactor(float value);
public static native void setGridRotation(float value);
public static native void setLighting(boolean enabled);
public static native void setBackfaceCulling(boolean enabled);
public static native void setWireframe(boolean enabled);
public static native void setCloudDensityLevel(int value);
public static native void setMeshAngleTolerance(float value);
public static native void setMeshTriangleSize(int value);
public static native void setClusterRatio(float value);
public static native void setMaxGainRadius(float value);
public static native void setRenderingTextureDecimation(int value);
public static native void setBackgroundColor(float gray);
public static native int setMappingParameter(String key, String value);
public static native void setPausedMapping(long nativeApplication, boolean paused);
public static native void setOnlineBlending(long nativeApplication, boolean enabled);
public static native void setMapCloudShown(long nativeApplication, boolean shown);
public static native void setOdomCloudShown(long nativeApplication, boolean shown);
public static native void setMeshRendering(long nativeApplication, boolean enabled, boolean withTexture);
public static native void setLocalizationMode(long nativeApplication, boolean enabled);
public static native void setTrajectoryMode(long nativeApplication, boolean enabled);
public static native void setGraphOptimization(long nativeApplication, boolean enabled);
public static native void setNodesFiltering(long nativeApplication, boolean enabled);
public static native void setGraphVisible(long nativeApplication, boolean visible);
public static native void setGridVisible(long nativeApplication, boolean visible);
public static native void setRawScanSaved(long nativeApplication, boolean enabled);
public static native void setFullResolution(long nativeApplication, boolean enabled);
public static native void setSmoothing(long nativeApplication, boolean enabled);
public static native void setDepthFromMotion(long nativeApplication, boolean enabled);
public static native void setCameraColor(long nativeApplication, boolean enabled);
public static native void setAppendMode(long nativeApplication, boolean enabled);
public static native void setDataRecorderMode(long nativeApplication, boolean enabled);
public static native void setMaxCloudDepth(long nativeApplication, float value);
public static native void setMinCloudDepth(long nativeApplication, float value);
public static native void setPointSize(long nativeApplication, float value);
public static native void setFOV(long nativeApplication, float value);
public static native void setOrthoCropFactor(long nativeApplication, float value);
public static native void setGridRotation(long nativeApplication, float value);
public static native void setLighting(long nativeApplication, boolean enabled);
public static native void setBackfaceCulling(long nativeApplication, boolean enabled);
public static native void setWireframe(long nativeApplication, boolean enabled);
public static native void setCloudDensityLevel(long nativeApplication, int value);
public static native void setMeshAngleTolerance(long nativeApplication, float value);
public static native void setMeshTriangleSize(long nativeApplication, int value);
public static native void setClusterRatio(long nativeApplication, float value);
public static native void setMaxGainRadius(long nativeApplication, float value);
public static native void setRenderingTextureDecimation(long nativeApplication, int value);
public static native void setBackgroundColor(long nativeApplication, float gray);
public static native int setMappingParameter(long nativeApplication, String key, String value);
public static native void setGPS(
long nativeApplication,
double stamp,
double longitude,
double latitude,
double altitude,
double accuracy,
double bearing);
public static native void addEnvSensor(long nativeApplication, int type, float value);
public static native void resetMapping();
public static native void save(String outputDatabasePath);
public static native void cancelProcessing();
public static native void save(long nativeApplication, String outputDatabasePath);
public static native void cancelProcessing(long nativeApplication);
public static native boolean exportMesh(
long nativeApplication,
float cloudVoxelSize,
boolean regenerateCloud,
boolean meshing,
@@ -120,15 +124,41 @@ public class RTABMapLib
float optimizedMaxTextureDistance,
int optimizedMinTextureClusterSize,
boolean blockRendering);
public static native boolean writeExportedMesh(String directory, String name);
public static native boolean postExportation(boolean visualize);
public static native int postProcessing(int approach);
public static native boolean writeExportedMesh(long nativeApplication, String directory, String name);
public static native boolean postExportation(long nativeApplication, boolean visualize);
public static native int postProcessing(long nativeApplication, int approach);
public static native String getStatus();
public static native int getTotalNodes();
public static native int getTotalWords();
public static native int getTotalPoints();
public static native float getUpdateTime();
public static native int getLoopClosureId();
public static native String getStatus(long nativeApplication);
public static native int getTotalNodes(long nativeApplication);
public static native int getTotalWords(long nativeApplication);
public static native int getTotalPoints(long nativeApplication);
public static native float getUpdateTime(long nativeApplication);
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
}

View File

@@ -43,12 +43,15 @@ public class Renderer implements GLSurfaceView.Renderer {
private float mSurfaceHeight = 0.0f;
private float mTextColor = 1.0f;
private int mOffset = 0;
private ARCoreSharedCamera mCamera = null;
private DisplayRotationHelper mDisplayRotationHelper = null;
private Vector<TextObject> mTexts;
private static RTABMapActivity mActivity;
public Renderer(RTABMapActivity c) {
mActivity = c;
mDisplayRotationHelper = new DisplayRotationHelper(/*context=*/ c);
}
private ProgressDialog mProgressDialog = null;
@@ -71,91 +74,129 @@ public class Renderer implements GLSurfaceView.Renderer {
{
mOffset = offset;
}
public void setCamera(ARCoreSharedCamera camera)
{
mCamera = camera;
if(mCamera!=null)
{
mDisplayRotationHelper.onDisplayChanged(0);
mDisplayRotationHelper.updateSessionIfNeeded(mCamera);
}
}
// Render loop of the Gl context.
public void onDrawFrame(GL10 useGLES20instead) {
try
{
final int value = RTABMapLib.render();
if(mTextManager!=null)
synchronized (this) {
if(mActivity.nativeApplication != 0)
{
if(mTextChanged)
int step = 0;
try
{
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);
}
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)
if(mCamera!=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.
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;
@@ -180,7 +221,10 @@ public class Renderer implements GLSurfaceView.Renderer {
// Called when the surface is created or recreated.
public void onSurfaceCreated(GL10 useGLES20instead, EGLConfig config) {
RTABMapLib.initGlContent();
if(mActivity.nativeApplication != 0)
{
RTABMapLib.initGlContent(mActivity.nativeApplication);
}
// Create our text manager
mTextManager = new TextManager(mActivity);

View File

@@ -7,11 +7,14 @@ import java.util.Arrays;
import java.util.Iterator;
import java.util.Map.Entry;
import android.Manifest;
import android.app.AlertDialog;
import android.content.DialogInterface;
import android.content.SharedPreferences;
import android.content.SharedPreferences.OnSharedPreferenceChangeListener;
import android.content.pm.PackageManager;
import android.os.Bundle;
import android.preference.CheckBoxPreference;
import android.preference.ListPreference;
import android.preference.Preference;
import android.preference.PreferenceActivity;
@@ -19,6 +22,7 @@ import android.text.InputType;
import android.view.WindowManager;
import android.view.inputmethod.EditorInfo;
import android.widget.EditText;
import android.widget.Toast;
public class SettingsActivity extends PreferenceActivity implements OnSharedPreferenceChangeListener {
@@ -34,7 +38,7 @@ public class SettingsActivity extends PreferenceActivity implements OnSharedPref
@Override
public boolean onPreferenceClick(Preference preference) {
getPreferenceScreen().getSharedPreferences().edit().clear().commit();
recreate();
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_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));
@@ -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_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_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));
@@ -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_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_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_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);
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_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_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_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));
@@ -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_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_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_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.
}
@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;
}
}
}
}

View File

@@ -66,6 +66,7 @@ public class SketchfabActivity extends Activity implements OnClickListener {
mButtonOk = (Button)findViewById(R.id.button_ok);
mProgressDialog = new ProgressDialog(this);
mProgressDialog.setCancelable(false);
mProgressDialog.setCanceledOnTouchOutside(false);
mAuthToken = getIntent().getExtras().getString(RTABMapActivity.RTABMAP_AUTH_TOKEN_KEY);
@@ -142,7 +143,8 @@ public class SketchfabActivity extends Activity implements OnClickListener {
if(!isNetworkAvailable())
{
// Visualize the result?
new AlertDialog.Builder(this)
AlertDialog ad = new AlertDialog.Builder(this)
.setCancelable(false)
.setTitle("Sharing to Sketchfab...")
.setMessage("Network is not available. Make sure you have internet before continuing.")
.setPositiveButton("Try Again", new DialogInterface.OnClickListener() {
@@ -154,7 +156,9 @@ public class SketchfabActivity extends Activity implements OnClickListener {
public void onClick(DialogInterface dialog, int which) {
}
})
.show();
.create();
ad.setCanceledOnTouchOutside(false);
ad.show();
return;
}
@@ -165,6 +169,8 @@ public class SketchfabActivity extends Activity implements OnClickListener {
WebView web;
mAuthDialog = new Dialog(this);
mAuthDialog.setCancelable(true);
mAuthDialog.setCanceledOnTouchOutside(true);
mAuthDialog.setContentView(R.layout.auth_dialog);
web = (WebView)mAuthDialog.findViewById(R.id.webv);
web.setWebContentsDebuggingEnabled(!RTABMapActivity.DISABLE_LOG);
@@ -200,7 +206,6 @@ public class SketchfabActivity extends Activity implements OnClickListener {
});
mAuthDialog.show();
mAuthDialog.setTitle("Authorize RTAB-Map");
mAuthDialog.setCancelable(true);
web.loadUrl(auth_url);
}
else
@@ -213,6 +218,8 @@ public class SketchfabActivity extends Activity implements OnClickListener {
{
mProgressDialog.setTitle("Upload to Sketchfab");
mProgressDialog.setMessage(String.format("Compressing the files..."));
mProgressDialog.setCancelable(false);
mProgressDialog.setCanceledOnTouchOutside(false);
mProgressDialog.show();
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);
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];
// verify if we have all files
@@ -308,7 +315,10 @@ public class SketchfabActivity extends Activity implements OnClickListener {
// 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();
}
}).create();
d.setCanceledOnTouchOutside(false);
d.show();
((TextView)d.findViewById(android.R.id.message)).setMovementMethod(LinkMovementMethod.getInstance());
}

View File

@@ -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);
}
}
}
}

View File

@@ -17,6 +17,7 @@ import android.graphics.Typeface;
import android.opengl.GLES20;
import android.opengl.GLUtils;
import android.text.TextPaint;
import android.util.Log;
public class TextManager {
@@ -50,7 +51,7 @@ public class TextManager {
public static final int RI_TEXT_TEXTURE_SIZE = 512; // 512
public static final float RI_TEXT_HEIGHT_BASE = 32.0f;
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;}
@@ -336,6 +337,8 @@ public class TextManager {
float y = val.y;
String text = val.text;
Log.i("RTABMapActivity", String.format("convertTextToTriangleInfo() set status=%s", text));
// Create
for(int j=0; j<text.length(); j++)
{

View File

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

68
app/ios/.gitignore vendored Normal file
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

View File

@@ -0,0 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<Workspace
version = "1.0">
<FileRef
location = "self:">
</FileRef>
</Workspace>

View File

@@ -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>

View File

@@ -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
}

View File

@@ -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
app/ios/RTABMapApp/.gitignore vendored Normal file
View File

@@ -0,0 +1 @@
Libraries

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.
}
}

View File

@@ -0,0 +1,11 @@
{
"colors" : [
{
"idiom" : "universal"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}

View File

@@ -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

View File

@@ -0,0 +1,6 @@
{
"info" : {
"author" : "xcode",
"version" : 1
}
}

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