mirror of
https://github.com/introlab/rtabmap.git
synced 2026-09-01 17:10:26 +08:00
Compare commits
131 Commits
0.21.3-iro
...
0.21.6-noe
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
24ca56248f | ||
|
|
0efd3c6b62 | ||
|
|
49d67302d5 | ||
|
|
41dcddc48e | ||
|
|
ccca53be03 | ||
|
|
08a44ec44f | ||
|
|
41fe47efdf | ||
|
|
7641f28250 | ||
|
|
f5a477f0f4 | ||
|
|
2fbe31f7cb | ||
|
|
623d056436 | ||
|
|
1611aa14f6 | ||
|
|
7d970ef020 | ||
|
|
1ab0133f14 | ||
|
|
4c1822683a | ||
|
|
7c601bb6e8 | ||
|
|
0d221a806f | ||
|
|
28fd696c18 | ||
|
|
c58fffe56d | ||
|
|
2a840fe340 | ||
|
|
0f03db9d7f | ||
|
|
4349f304d2 | ||
|
|
80a4ce02c9 | ||
|
|
b37f7d6351 | ||
|
|
35d4bd768c | ||
|
|
e6691658bd | ||
|
|
3cfcccdb1d | ||
|
|
8310925c81 | ||
|
|
99cb02fdff | ||
|
|
8b372b52ac | ||
|
|
c25add868a | ||
|
|
91cbbc8238 | ||
|
|
ccdddfc83f | ||
|
|
9b255d1f27 | ||
|
|
3ab8ae7eaf | ||
|
|
a327c9530c | ||
|
|
5b810da73b | ||
|
|
098301e52c | ||
|
|
2f21d42555 | ||
|
|
fc9dcd6b3d | ||
|
|
0ad1d0ad69 | ||
|
|
ce0c806d75 | ||
|
|
fb37b3adba | ||
|
|
0f961783c1 | ||
|
|
32e03aaf68 | ||
|
|
03afb94d92 | ||
|
|
c5c190a2a0 | ||
|
|
bc66060fab | ||
|
|
3d5f1ad5c2 | ||
|
|
41a7eff8fa | ||
|
|
6acec02dbe | ||
|
|
fbeabf0751 | ||
|
|
0d4e4730c7 | ||
|
|
995f65b2ec | ||
|
|
c034a9631c | ||
|
|
256dcbded4 | ||
|
|
812caeeb9a | ||
|
|
a66564f98f | ||
|
|
375597af00 | ||
|
|
72d7418011 | ||
|
|
9505a21a7e | ||
|
|
36304b2cd1 | ||
|
|
f3cfa7831d | ||
|
|
99c4612c64 | ||
|
|
27dea71398 | ||
|
|
726bceb816 | ||
|
|
700704bec9 | ||
|
|
6a6913c939 | ||
|
|
a55b4203cd | ||
|
|
a3267c9da6 | ||
|
|
fbbab1c077 | ||
|
|
4e7110930c | ||
|
|
9266926a4a | ||
|
|
5a159cef04 | ||
|
|
5ed1bf0ca8 | ||
|
|
c33e995e83 | ||
|
|
92edae35fc | ||
|
|
d794669ef9 | ||
|
|
9cb0046734 | ||
|
|
76f63ab79a | ||
|
|
063ca9c8ee | ||
|
|
11adbdcc9f | ||
|
|
8612ebba93 | ||
|
|
a0476af896 | ||
|
|
3b735907c8 | ||
|
|
0ba79be461 | ||
|
|
cc17ebe92b | ||
|
|
bfeb487dba | ||
|
|
bc6d390fb6 | ||
|
|
f8a63ecf10 | ||
|
|
7183b43c2a | ||
|
|
fa3ece5183 | ||
|
|
2f132b3a40 | ||
|
|
79dc180bf4 | ||
|
|
264c560a2c | ||
|
|
4ce36ef245 | ||
|
|
d0227694c5 | ||
|
|
a6d9425bce | ||
|
|
e299505a64 | ||
|
|
57b4954cb3 | ||
|
|
2577c47e77 | ||
|
|
52e1b01597 | ||
|
|
8019a2dc49 | ||
|
|
33b875ecbf | ||
|
|
c24f95a8d9 | ||
|
|
6f7e5cc97b | ||
|
|
fccf33dd96 | ||
|
|
752ca76cf5 | ||
|
|
81e249b56c | ||
|
|
ff7c8af56f | ||
|
|
a11ea291d8 | ||
|
|
cd615c6e52 | ||
|
|
1bd2d9fe81 | ||
|
|
510aef19e4 | ||
|
|
1dadd50cf2 | ||
|
|
b2a86d640a | ||
|
|
c27507bc77 | ||
|
|
b374c6cd8e | ||
|
|
29dc6c67fa | ||
|
|
10de748531 | ||
|
|
dcd5994456 | ||
|
|
13cd5e7a5e | ||
|
|
856e372dde | ||
|
|
423e67558b | ||
|
|
ace653593b | ||
|
|
7b31c737be | ||
|
|
0b534c9427 | ||
|
|
cdbdcfe676 | ||
|
|
b7239fdc84 | ||
|
|
a0559b156b | ||
|
|
f8c4b62591 |
@@ -19,7 +19,7 @@ init:
|
|||||||
install:
|
install:
|
||||||
# To download from google drive
|
# To download from google drive
|
||||||
- set PATH=C:\Python38-x64;C:\Python38-x64\Scripts;%PATH%
|
- set PATH=C:\Python38-x64;C:\Python38-x64\Scripts;%PATH%
|
||||||
- ps: py -m pip --disable-pip-version-check install gdown
|
- ps: py -m pip --disable-pip-version-check install gdown>=5.1.0
|
||||||
# Qt
|
# Qt
|
||||||
- set QTDIR=C:\Qt\5.10.1\msvc2015_64
|
- set QTDIR=C:\Qt\5.10.1\msvc2015_64
|
||||||
# make sure Qt bin path is before cmake bin path to avoid copying qt5 dlls from cmake before qt installation
|
# make sure Qt bin path is before cmake bin path to avoid copying qt5 dlls from cmake before qt installation
|
||||||
|
|||||||
8
.devcontainer/android/devcontainer.json
Normal file
8
.devcontainer/android/devcontainer.json
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
{
|
||||||
|
"image": "introlab3it/rtabmap:android-deps",
|
||||||
|
"customizations": {
|
||||||
|
"vscode": {
|
||||||
|
"extensions": ["ms-vscode.cpptools-themes", "ms-vscode.cmake-tools", "vscjava.vscode-java-pack"]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
8
.devcontainer/bionic/devcontainer.json
Normal file
8
.devcontainer/bionic/devcontainer.json
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
{
|
||||||
|
"image": "introlab3it/rtabmap:18.04",
|
||||||
|
"customizations": {
|
||||||
|
"vscode": {
|
||||||
|
"extensions": ["ms-vscode.cpptools-themes", "ms-vscode.cmake-tools"]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -2,7 +2,7 @@
|
|||||||
"image": "introlab3it/rtabmap:20.04",
|
"image": "introlab3it/rtabmap:20.04",
|
||||||
"customizations": {
|
"customizations": {
|
||||||
"vscode": {
|
"vscode": {
|
||||||
"extensions": ["ms-vscode.cpptools-themes", "ms-vscode.cmake-tools", "vscjava.vscode-java-pack"]
|
"extensions": ["ms-vscode.cpptools-themes", "ms-vscode.cmake-tools"]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
8
.devcontainer/jammy/devcontainer.json
Normal file
8
.devcontainer/jammy/devcontainer.json
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
{
|
||||||
|
"image": "introlab3it/rtabmap:22.04",
|
||||||
|
"customizations": {
|
||||||
|
"vscode": {
|
||||||
|
"extensions": ["ms-vscode.cpptools-themes", "ms-vscode.cmake-tools"]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
8
.devcontainer/noble/devcontainer.json
Normal file
8
.devcontainer/noble/devcontainer.json
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
{
|
||||||
|
"image": "introlab3it/rtabmap:24.04",
|
||||||
|
"customizations": {
|
||||||
|
"vscode": {
|
||||||
|
"extensions": ["ms-vscode.cpptools-themes", "ms-vscode.cmake-tools"]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
3
.github/workflows/cmake-ros.yml
vendored
3
.github/workflows/cmake-ros.yml
vendored
@@ -31,6 +31,9 @@ jobs:
|
|||||||
os: ubuntu-22.04
|
os: ubuntu-22.04
|
||||||
- ros_distribution: 'iron'
|
- ros_distribution: 'iron'
|
||||||
os: ubuntu-22.04
|
os: ubuntu-22.04
|
||||||
|
# Currently CI has some errors on setup-ros with this OS, disabling for now
|
||||||
|
#- ros_distribution: 'jazzy'
|
||||||
|
# os: ubuntu-24.04
|
||||||
|
|
||||||
steps:
|
steps:
|
||||||
- uses: ros-tooling/setup-ros@v0.6
|
- uses: ros-tooling/setup-ros@v0.6
|
||||||
|
|||||||
2
.github/workflows/cmake.yml
vendored
2
.github/workflows/cmake.yml
vendored
@@ -18,7 +18,7 @@ jobs:
|
|||||||
strategy:
|
strategy:
|
||||||
fail-fast: false
|
fail-fast: false
|
||||||
matrix:
|
matrix:
|
||||||
os: [ubuntu-22.04, ubuntu-20.04]
|
os: [ubuntu-24.04, ubuntu-22.04, ubuntu-20.04]
|
||||||
|
|
||||||
steps:
|
steps:
|
||||||
- name: Install dependencies
|
- name: Install dependencies
|
||||||
|
|||||||
23
.github/workflows/docker.yml
vendored
23
.github/workflows/docker.yml
vendored
@@ -12,7 +12,7 @@ jobs:
|
|||||||
strategy:
|
strategy:
|
||||||
fail-fast: false
|
fail-fast: false
|
||||||
matrix:
|
matrix:
|
||||||
docker_tag: [focal-deps, jammy-deps, jammy-iron-deps]
|
docker_tag: [focal-deps, jammy-deps, jammy-iron-deps, noble-deps]
|
||||||
include:
|
include:
|
||||||
- docker_tag: focal-deps
|
- docker_tag: focal-deps
|
||||||
docker_tags: |
|
docker_tags: |
|
||||||
@@ -20,6 +20,7 @@ jobs:
|
|||||||
docker_platforms: |
|
docker_platforms: |
|
||||||
linux/amd64
|
linux/amd64
|
||||||
linux/arm64
|
linux/arm64
|
||||||
|
linux/arm/v7
|
||||||
docker_path: 'focal/deps'
|
docker_path: 'focal/deps'
|
||||||
- docker_tag: jammy-deps
|
- docker_tag: jammy-deps
|
||||||
docker_tags: |
|
docker_tags: |
|
||||||
@@ -34,6 +35,13 @@ jobs:
|
|||||||
docker_platforms: |
|
docker_platforms: |
|
||||||
linux/amd64
|
linux/amd64
|
||||||
docker_path: 'jammy-iron/deps'
|
docker_path: 'jammy-iron/deps'
|
||||||
|
- docker_tag: noble-deps
|
||||||
|
docker_tags: |
|
||||||
|
introlab3it/rtabmap:noble-deps
|
||||||
|
docker_platforms: |
|
||||||
|
linux/amd64
|
||||||
|
linux/arm64
|
||||||
|
docker_path: 'noble/deps'
|
||||||
|
|
||||||
steps:
|
steps:
|
||||||
-
|
-
|
||||||
@@ -72,7 +80,7 @@ jobs:
|
|||||||
strategy:
|
strategy:
|
||||||
fail-fast: false
|
fail-fast: false
|
||||||
matrix:
|
matrix:
|
||||||
docker_tag: [bionic, focal, jammy, jammy-iron, android23, android24, android26, android30]
|
docker_tag: [bionic, focal, jammy, jammy-iron, noble, android23, android24, android26, android30]
|
||||||
include:
|
include:
|
||||||
- docker_tag: bionic
|
- docker_tag: bionic
|
||||||
docker_tags: |
|
docker_tags: |
|
||||||
@@ -94,6 +102,7 @@ jobs:
|
|||||||
docker_platforms: |
|
docker_platforms: |
|
||||||
linux/amd64
|
linux/amd64
|
||||||
linux/arm64
|
linux/arm64
|
||||||
|
linux/arm/v7
|
||||||
docker_path: 'focal'
|
docker_path: 'focal'
|
||||||
- docker_tag: jammy
|
- docker_tag: jammy
|
||||||
docker_tags: |
|
docker_tags: |
|
||||||
@@ -113,6 +122,16 @@ jobs:
|
|||||||
docker_platforms: |
|
docker_platforms: |
|
||||||
linux/amd64
|
linux/amd64
|
||||||
docker_path: 'jammy-iron'
|
docker_path: 'jammy-iron'
|
||||||
|
- docker_tag: noble
|
||||||
|
docker_tags: |
|
||||||
|
introlab3it/rtabmap:noble
|
||||||
|
introlab3it/rtabmap:24.04
|
||||||
|
docker_args: |
|
||||||
|
NOT_USED=0
|
||||||
|
docker_platforms: |
|
||||||
|
linux/amd64
|
||||||
|
linux/arm64
|
||||||
|
docker_path: 'noble'
|
||||||
- docker_tag: android23
|
- docker_tag: android23
|
||||||
docker_tags: |
|
docker_tags: |
|
||||||
introlab3it/rtabmap:android23
|
introlab3it/rtabmap:android23
|
||||||
|
|||||||
16
.github/workflows/scheduled-stats.yml
vendored
Normal file
16
.github/workflows/scheduled-stats.yml
vendored
Normal file
@@ -0,0 +1,16 @@
|
|||||||
|
name: RTAB-Map Scheduled Stats Extraction From GitHub
|
||||||
|
|
||||||
|
on:
|
||||||
|
workflow_dispatch:
|
||||||
|
schedule:
|
||||||
|
- cron: '0 5 * * *'
|
||||||
|
jobs:
|
||||||
|
get_stats:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
steps:
|
||||||
|
- name: Update Stats
|
||||||
|
uses: introlab/github-stats-action@v1
|
||||||
|
with:
|
||||||
|
github-stats-token: ${{ secrets.STATS_TOKEN }}
|
||||||
|
google-application-credentials: ${{ secrets.GOOGLE_APPLICATION_CREDENTIALS }}
|
||||||
|
spreadsheet-id: ${{ secrets.SPREADSHEET_ID }}
|
||||||
103
CMakeLists.txt
103
CMakeLists.txt
@@ -1,5 +1,5 @@
|
|||||||
# Top-Level CmakeLists.txt
|
# Top-Level CmakeLists.txt
|
||||||
cmake_minimum_required(VERSION 3.10)
|
cmake_minimum_required(VERSION 3.14)
|
||||||
PROJECT( RTABMap )
|
PROJECT( RTABMap )
|
||||||
SET(PROJECT_PREFIX rtabmap)
|
SET(PROJECT_PREFIX rtabmap)
|
||||||
|
|
||||||
@@ -20,7 +20,7 @@ SET(CMAKE_MODULE_PATH "${PROJECT_SOURCE_DIR}/cmake_modules")
|
|||||||
#######################
|
#######################
|
||||||
SET(RTABMAP_MAJOR_VERSION 0)
|
SET(RTABMAP_MAJOR_VERSION 0)
|
||||||
SET(RTABMAP_MINOR_VERSION 21)
|
SET(RTABMAP_MINOR_VERSION 21)
|
||||||
SET(RTABMAP_PATCH_VERSION 3)
|
SET(RTABMAP_PATCH_VERSION 6)
|
||||||
SET(RTABMAP_VERSION
|
SET(RTABMAP_VERSION
|
||||||
${RTABMAP_MAJOR_VERSION}.${RTABMAP_MINOR_VERSION}.${RTABMAP_PATCH_VERSION})
|
${RTABMAP_MAJOR_VERSION}.${RTABMAP_MINOR_VERSION}.${RTABMAP_PATCH_VERSION})
|
||||||
|
|
||||||
@@ -181,6 +181,7 @@ option(WITH_FREENECT "Include Freenect support" ON)
|
|||||||
option(WITH_FREENECT2 "Include Freenect2 support" ON)
|
option(WITH_FREENECT2 "Include Freenect2 support" ON)
|
||||||
option(WITH_K4W2 "Include Kinect for Windows v2 support" ON)
|
option(WITH_K4W2 "Include Kinect for Windows v2 support" ON)
|
||||||
option(WITH_K4A "Include Kinect for Azure support" ON)
|
option(WITH_K4A "Include Kinect for Azure support" ON)
|
||||||
|
option(WITH_OPENNI "Include OpenNI support" ON)
|
||||||
option(WITH_OPENNI2 "Include OpenNI2 support" ON)
|
option(WITH_OPENNI2 "Include OpenNI2 support" ON)
|
||||||
option(WITH_DC1394 "Include dc1394 support" ON)
|
option(WITH_DC1394 "Include dc1394 support" ON)
|
||||||
option(WITH_G2O "Include g2o support" ON)
|
option(WITH_G2O "Include g2o support" ON)
|
||||||
@@ -203,6 +204,7 @@ option(WITH_REALSENSE_SLAM "Include RealSenseSlam support" ON)
|
|||||||
option(WITH_REALSENSE2 "Include RealSense support" ON)
|
option(WITH_REALSENSE2 "Include RealSense support" ON)
|
||||||
option(WITH_MYNTEYE "Include mynteye-s support" ON)
|
option(WITH_MYNTEYE "Include mynteye-s support" ON)
|
||||||
option(WITH_DEPTHAI "Include depthai-core support" OFF)
|
option(WITH_DEPTHAI "Include depthai-core support" OFF)
|
||||||
|
option(WITH_XVSDK "Include XVisio SDK support" OFF)
|
||||||
option(WITH_OCTOMAP "Include OctoMap support" ON)
|
option(WITH_OCTOMAP "Include OctoMap support" ON)
|
||||||
option(WITH_GRIDMAP "Include GridMap support" ON)
|
option(WITH_GRIDMAP "Include GridMap support" ON)
|
||||||
option(WITH_CPUTSDF "Include CPUTSDF support" OFF)
|
option(WITH_CPUTSDF "Include CPUTSDF support" OFF)
|
||||||
@@ -252,10 +254,10 @@ endif()
|
|||||||
|
|
||||||
FIND_PACKAGE(ZLIB REQUIRED QUIET)
|
FIND_PACKAGE(ZLIB REQUIRED QUIET)
|
||||||
|
|
||||||
FIND_PACKAGE(Sqlite3 QUIET)
|
FIND_PACKAGE(SQLite3 QUIET)
|
||||||
IF(Sqlite3_FOUND)
|
IF(SQLite3_FOUND)
|
||||||
MESSAGE(STATUS "Found Sqlite3: ${Sqlite3_INCLUDE_DIRS} ${Sqlite3_LIBRARIES}")
|
MESSAGE(STATUS "Found SQLite3: ${SQLite3_INCLUDE_DIRS} ${SQLite3_LIBRARIES}")
|
||||||
ENDIF(Sqlite3_FOUND)
|
ENDIF(SQLite3_FOUND)
|
||||||
|
|
||||||
if(NOT "${PCL_LIBRARIES}" STREQUAL "")
|
if(NOT "${PCL_LIBRARIES}" STREQUAL "")
|
||||||
# fix libproj.so not found on Xenial
|
# fix libproj.so not found on Xenial
|
||||||
@@ -294,14 +296,20 @@ SET(ADD_VTK_GUI_SUPPORT_QT_TO_CONF FALSE)
|
|||||||
IF(WITH_QT)
|
IF(WITH_QT)
|
||||||
FIND_PACKAGE(VTK)
|
FIND_PACKAGE(VTK)
|
||||||
IF(NOT VTK_FOUND)
|
IF(NOT VTK_FOUND)
|
||||||
MESSAGE(FATAL_ERROR "VTK is required when using Qt. Set -DWITH_QT=OFF if you don't want gui tools.")
|
MESSAGE(FATAL_ERROR "VTK is required when using Qt. Set -DWITH_QT=OFF if you don't want gui tools.")
|
||||||
ENDIF(NOT VTK_FOUND)
|
ENDIF(NOT VTK_FOUND)
|
||||||
|
|
||||||
# If Qt is here, the GUI will be built
|
# If Qt is here, the GUI will be built
|
||||||
IF(NOT(${VTK_MAJOR_VERSION} LESS 9))
|
IF(NOT(${VTK_MAJOR_VERSION} LESS 9))
|
||||||
IF(NOT VTK_QT_VERSION)
|
IF(NOT VTK_QT_VERSION)
|
||||||
MESSAGE(FATAL_ERROR "WITH_QT option is ON, but VTK ${VTK_MAJOR_VERSION} has not been built with Qt support, disabling Qt.")
|
MESSAGE(FATAL_ERROR "WITH_QT option is ON, but VTK ${VTK_MAJOR_VERSION} has not been built with Qt support, disabling Qt.")
|
||||||
ENDIF()
|
ENDIF()
|
||||||
|
|
||||||
|
option(VTK_GLOBAL_WARNING_DISPLAY "Show VTK warning display on runtime" OFF)
|
||||||
|
IF(NOT VTK_GLOBAL_WARNING_DISPLAY)
|
||||||
|
ADD_DEFINITIONS(-DVTK_GLOBAL_WARNING_DISPLAY_OFF)
|
||||||
|
ENDIF()
|
||||||
|
|
||||||
MESSAGE(STATUS "VTK>=9 detected, will use VTK_QT_VERSION=${VTK_QT_VERSION} for Qt version.")
|
MESSAGE(STATUS "VTK>=9 detected, will use VTK_QT_VERSION=${VTK_QT_VERSION} for Qt version.")
|
||||||
IF(${VTK_QT_VERSION} EQUAL 6)
|
IF(${VTK_QT_VERSION} EQUAL 6)
|
||||||
FIND_PACKAGE(Qt6 COMPONENTS Widgets Core Gui OpenGL PrintSupport QUIET OPTIONAL_COMPONENTS Svg)
|
FIND_PACKAGE(Qt6 COMPONENTS Widgets Core Gui OpenGL PrintSupport QUIET OPTIONAL_COMPONENTS Svg)
|
||||||
@@ -533,6 +541,11 @@ IF(WITH_POINTMATCHER)
|
|||||||
message(STATUS "libnabo found, version ${libnabo_VERSION} (Config mode)")
|
message(STATUS "libnabo found, version ${libnabo_VERSION} (Config mode)")
|
||||||
SET(libpointmatcher_LIBRARIES "${libpointmatcher_LIBRARIES};libnabo::nabo")
|
SET(libpointmatcher_LIBRARIES "${libpointmatcher_LIBRARIES};libnabo::nabo")
|
||||||
ENDIF(value EQUAL -1)
|
ENDIF(value EQUAL -1)
|
||||||
|
string(FIND "${libpointmatcher_LIBRARIES}" "yaml-cpp::yaml-cpp" value)
|
||||||
|
IF(NOT value EQUAL -1)
|
||||||
|
# Find yaml-cpp (Issue #1268):
|
||||||
|
find_package(yaml-cpp QUIET)
|
||||||
|
ENDIF(NOT value EQUAL -1)
|
||||||
ENDIF(libpointmatcher_FOUND)
|
ENDIF(libpointmatcher_FOUND)
|
||||||
ENDIF(WITH_POINTMATCHER)
|
ENDIF(WITH_POINTMATCHER)
|
||||||
|
|
||||||
@@ -645,12 +658,19 @@ IF(WITH_MYNTEYE)
|
|||||||
ENDIF(WITH_MYNTEYE)
|
ENDIF(WITH_MYNTEYE)
|
||||||
|
|
||||||
IF(WITH_DEPTHAI)
|
IF(WITH_DEPTHAI)
|
||||||
FIND_PACKAGE(depthai 2 QUIET)
|
FIND_PACKAGE(depthai 2.24 QUIET)
|
||||||
IF(depthai_FOUND)
|
IF(depthai_FOUND)
|
||||||
MESSAGE(STATUS "Found depthai-core (targets)")
|
MESSAGE(STATUS "Found depthai-core (targets)")
|
||||||
ENDIF(depthai_FOUND)
|
ENDIF(depthai_FOUND)
|
||||||
ENDIF(WITH_DEPTHAI)
|
ENDIF(WITH_DEPTHAI)
|
||||||
|
|
||||||
|
IF(WITH_XVSDK)
|
||||||
|
FIND_PACKAGE(xvsdk QUIET)
|
||||||
|
IF(xvsdk_FOUND)
|
||||||
|
MESSAGE(STATUS "Found xvsdk (targets)")
|
||||||
|
ENDIF(xvsdk_FOUND)
|
||||||
|
ENDIF(WITH_XVSDK)
|
||||||
|
|
||||||
IF(WITH_OCTOMAP)
|
IF(WITH_OCTOMAP)
|
||||||
FIND_PACKAGE(octomap QUIET)
|
FIND_PACKAGE(octomap QUIET)
|
||||||
IF(octomap_FOUND)
|
IF(octomap_FOUND)
|
||||||
@@ -886,9 +906,9 @@ ENDIF()
|
|||||||
IF(NOT MRPT_FOUND)
|
IF(NOT MRPT_FOUND)
|
||||||
SET(MRPT "//")
|
SET(MRPT "//")
|
||||||
ENDIF(NOT MRPT_FOUND)
|
ENDIF(NOT MRPT_FOUND)
|
||||||
IF(NOT CERES_FOUND)
|
IF(NOT WITH_CERES OR NOT CERES_FOUND)
|
||||||
SET(CERES "//")
|
SET(CERES "//")
|
||||||
ENDIF(NOT CERES_FOUND)
|
ENDIF(NOT WITH_CERES OR NOT CERES_FOUND)
|
||||||
IF(NOT WITH_TORO)
|
IF(NOT WITH_TORO)
|
||||||
SET(TORO "//")
|
SET(TORO "//")
|
||||||
ENDIF(NOT WITH_TORO)
|
ENDIF(NOT WITH_TORO)
|
||||||
@@ -945,6 +965,9 @@ ELSE()
|
|||||||
)
|
)
|
||||||
ENDIF(WIN32)
|
ENDIF(WIN32)
|
||||||
ENDIF()
|
ENDIF()
|
||||||
|
IF(NOT (OpenNI_FOUND AND WITH_OPENNI))
|
||||||
|
SET(OPENNI "//")
|
||||||
|
ENDIF()
|
||||||
IF(NOT OpenNI2_FOUND)
|
IF(NOT OpenNI2_FOUND)
|
||||||
SET(OPENNI2 "//")
|
SET(OPENNI2 "//")
|
||||||
ENDIF()
|
ENDIF()
|
||||||
@@ -989,6 +1012,12 @@ IF(NOT depthai_FOUND)
|
|||||||
ELSE()
|
ELSE()
|
||||||
SET(CONF_WITH_DEPTH_AI 1)
|
SET(CONF_WITH_DEPTH_AI 1)
|
||||||
ENDIF()
|
ENDIF()
|
||||||
|
IF(NOT xvsdk_FOUND)
|
||||||
|
SET(XVSDK "//")
|
||||||
|
SET(CONF_WITH_XVSDK 0)
|
||||||
|
ELSE()
|
||||||
|
SET(CONF_WITH_XVSDK 1)
|
||||||
|
ENDIF()
|
||||||
IF(NOT octomap_FOUND)
|
IF(NOT octomap_FOUND)
|
||||||
SET(OCTOMAP "//")
|
SET(OCTOMAP "//")
|
||||||
SET(CONF_WITH_OCTOMAP 0)
|
SET(CONF_WITH_OCTOMAP 0)
|
||||||
@@ -1064,13 +1093,15 @@ IF(ANDROID)
|
|||||||
IF(BUILD_APP)
|
IF(BUILD_APP)
|
||||||
ADD_SUBDIRECTORY( app )
|
ADD_SUBDIRECTORY( app )
|
||||||
ENDIF(BUILD_APP)
|
ENDIF(BUILD_APP)
|
||||||
ELSEIF(Qt6_FOUND OR Qt5_FOUND OR (QT4_FOUND AND QT_QTCORE_FOUND AND QT_QTGUI_FOUND))
|
|
||||||
ADD_SUBDIRECTORY( guilib )
|
|
||||||
IF(BUILD_APP)
|
|
||||||
ADD_SUBDIRECTORY( app )
|
|
||||||
ENDIF(BUILD_APP)
|
|
||||||
ELSEIF(WITH_QT)
|
ELSEIF(WITH_QT)
|
||||||
MESSAGE(WARNING "Qt not found, the GUI lib and the stand-alone application will not be compiled...")
|
IF(Qt6_FOUND OR Qt5_FOUND OR (QT4_FOUND AND QT_QTCORE_FOUND AND QT_QTGUI_FOUND))
|
||||||
|
ADD_SUBDIRECTORY( guilib )
|
||||||
|
IF(BUILD_APP)
|
||||||
|
ADD_SUBDIRECTORY( app )
|
||||||
|
ENDIF(BUILD_APP)
|
||||||
|
ELSE()
|
||||||
|
MESSAGE(WARNING "Qt not found, the GUI lib and the stand-alone application will not be compiled...")
|
||||||
|
ENDIF()
|
||||||
ENDIF()
|
ENDIF()
|
||||||
|
|
||||||
IF(BUILD_TOOLS)
|
IF(BUILD_TOOLS)
|
||||||
@@ -1098,7 +1129,7 @@ ENDIF()
|
|||||||
####
|
####
|
||||||
add_library(rtabmap INTERFACE)
|
add_library(rtabmap INTERFACE)
|
||||||
add_library(rtabmap::rtabmap ALIAS rtabmap)
|
add_library(rtabmap::rtabmap ALIAS rtabmap)
|
||||||
IF(QT4_FOUND OR Qt5_FOUND OR Qt6_FOUND)
|
IF(WITH_QT AND (QT4_FOUND OR Qt5_FOUND OR Qt6_FOUND))
|
||||||
set(CONF_WITH_GUI ON)
|
set(CONF_WITH_GUI ON)
|
||||||
IF(QT4_FOUND)
|
IF(QT4_FOUND)
|
||||||
set(CONF_QT_VERSION 4)
|
set(CONF_QT_VERSION 4)
|
||||||
@@ -1310,13 +1341,13 @@ IF(OpenCV_FOUND)
|
|||||||
ENDIF()
|
ENDIF()
|
||||||
ENDIF(OpenCV_FOUND)
|
ENDIF(OpenCV_FOUND)
|
||||||
|
|
||||||
IF(QT4_FOUND)
|
IF(WITH_QT AND QT4_FOUND)
|
||||||
MESSAGE(STATUS " With Qt4 = YES (License: Open Source or Commercial)")
|
MESSAGE(STATUS " With Qt4 = YES (License: Open Source or Commercial)")
|
||||||
MESSAGE(STATUS " With VTK ${VTK_MAJOR_VERSION}.${VTK_MINOR_VERSION} = YES (License: BSD)")
|
MESSAGE(STATUS " With VTK ${VTK_MAJOR_VERSION}.${VTK_MINOR_VERSION} = YES (License: BSD)")
|
||||||
ELSEIF(Qt5_FOUND)
|
ELSEIF(WITH_QT AND Qt5_FOUND)
|
||||||
MESSAGE(STATUS " With Qt ${Qt5_VERSION} = YES (License: Open Source or Commercial)")
|
MESSAGE(STATUS " With Qt ${Qt5_VERSION} = YES (License: Open Source or Commercial)")
|
||||||
MESSAGE(STATUS " With VTK ${VTK_MAJOR_VERSION}.${VTK_MINOR_VERSION} = YES (License: BSD)")
|
MESSAGE(STATUS " With VTK ${VTK_MAJOR_VERSION}.${VTK_MINOR_VERSION} = YES (License: BSD)")
|
||||||
ELSEIF(Qt6_FOUND)
|
ELSEIF(WITH_QT AND Qt6_FOUND)
|
||||||
MESSAGE(STATUS " With Qt ${Qt6_VERSION} = YES (License: Open Source or Commercial)")
|
MESSAGE(STATUS " With Qt ${Qt6_VERSION} = YES (License: Open Source or Commercial)")
|
||||||
MESSAGE(STATUS " With VTK ${VTK_MAJOR_VERSION}.${VTK_MINOR_VERSION} = YES (License: BSD)")
|
MESSAGE(STATUS " With VTK ${VTK_MAJOR_VERSION}.${VTK_MINOR_VERSION} = YES (License: BSD)")
|
||||||
|
|
||||||
@@ -1326,10 +1357,10 @@ ELSE()
|
|||||||
MESSAGE(STATUS " With Qt = NO (Qt not found)")
|
MESSAGE(STATUS " With Qt = NO (Qt not found)")
|
||||||
ENDIF()
|
ENDIF()
|
||||||
|
|
||||||
IF(Sqlite3_FOUND)
|
IF(SQLite3_FOUND)
|
||||||
MESSAGE(STATUS " With external SQLite3 = YES (License: Public Domain)")
|
MESSAGE(STATUS " With external SQLite3 = YES (License: Public Domain)")
|
||||||
ELSE()
|
ELSE()
|
||||||
MESSAGE(STATUS " With external SQLite3 = NO (sqlite3 not found, internal version is used for convenience)")
|
MESSAGE(STATUS " With external SQLite3 = NO (SQLite3 not found, internal version is used for convenience)")
|
||||||
ENDIF()
|
ENDIF()
|
||||||
|
|
||||||
IF(WITH_ORB_OCTREE)
|
IF(WITH_ORB_OCTREE)
|
||||||
@@ -1400,12 +1431,8 @@ ELSE()
|
|||||||
MESSAGE(STATUS " *With GTSAM = NO (GTSAM not found)")
|
MESSAGE(STATUS " *With GTSAM = NO (GTSAM not found)")
|
||||||
ENDIF()
|
ENDIF()
|
||||||
|
|
||||||
IF(CERES_FOUND)
|
IF(WITH_CERES AND CERES_FOUND)
|
||||||
IF(WITH_CERES)
|
|
||||||
MESSAGE(STATUS " *With Ceres ${Ceres_VERSION} = YES (License: BSD)")
|
MESSAGE(STATUS " *With Ceres ${Ceres_VERSION} = YES (License: BSD)")
|
||||||
ELSE()
|
|
||||||
MESSAGE(STATUS " *With Ceres ${Ceres_VERSION} = YES (License: BSD, WITH_CERES=OFF but it is enabled by okvis or floam dependencies)")
|
|
||||||
ENDIF()
|
|
||||||
ELSEIF(NOT WITH_CERES)
|
ELSEIF(NOT WITH_CERES)
|
||||||
MESSAGE(STATUS " *With Ceres = NO (WITH_CERES=OFF)")
|
MESSAGE(STATUS " *With Ceres = NO (WITH_CERES=OFF)")
|
||||||
ELSE()
|
ELSE()
|
||||||
@@ -1524,6 +1551,14 @@ ELSE()
|
|||||||
MESSAGE(STATUS " With Freenect = NO (libfreenect not found)")
|
MESSAGE(STATUS " With Freenect = NO (libfreenect not found)")
|
||||||
ENDIF()
|
ENDIF()
|
||||||
|
|
||||||
|
IF(WITH_OPENNI AND OpenNI_FOUND)
|
||||||
|
MESSAGE(STATUS " With OpenNI = YES (License: Apache v2)")
|
||||||
|
ELSEIF(NOT WITH_OPENNI)
|
||||||
|
MESSAGE(STATUS " With OpenNI = NO (WITH_OPENNI=OFF)")
|
||||||
|
ELSE()
|
||||||
|
MESSAGE(STATUS " With OpenNI = NO (OpenNI not found)")
|
||||||
|
ENDIF()
|
||||||
|
|
||||||
IF(OpenNI2_FOUND)
|
IF(OpenNI2_FOUND)
|
||||||
MESSAGE(STATUS " With OpenNI2 = YES (License: Apache v2)")
|
MESSAGE(STATUS " With OpenNI2 = YES (License: Apache v2)")
|
||||||
ELSEIF(NOT WITH_OPENNI2)
|
ELSEIF(NOT WITH_OPENNI2)
|
||||||
@@ -1631,6 +1666,14 @@ ELSE()
|
|||||||
MESSAGE(STATUS " With DepthAI = NO (depthai-core not found)")
|
MESSAGE(STATUS " With DepthAI = NO (depthai-core not found)")
|
||||||
ENDIF()
|
ENDIF()
|
||||||
|
|
||||||
|
IF(xvsdk_FOUND)
|
||||||
|
MESSAGE(STATUS " With XVisio SDK ${xvsdk_VERSION} = YES")
|
||||||
|
ELSEIF(NOT WITH_XVSDK)
|
||||||
|
MESSAGE(STATUS " With XVisio SDK = NO (WITH_XVSDK=OFF)")
|
||||||
|
ELSE()
|
||||||
|
MESSAGE(STATUS " With XVisio SDK = NO (xvsdk not found)")
|
||||||
|
ENDIF()
|
||||||
|
|
||||||
MESSAGE(STATUS "")
|
MESSAGE(STATUS "")
|
||||||
MESSAGE(STATUS " Odometry Approaches:")
|
MESSAGE(STATUS " Odometry Approaches:")
|
||||||
IF(loam_velodyne_FOUND)
|
IF(loam_velodyne_FOUND)
|
||||||
|
|||||||
@@ -7,7 +7,7 @@ rtabmap
|
|||||||
[![Downloads][downloads-image]][downloads]
|
[![Downloads][downloads-image]][downloads]
|
||||||
[![License][license-image]][license]
|
[![License][license-image]][license]
|
||||||
|
|
||||||
[release-image]: https://img.shields.io/badge/release-0.21.0-green.svg?style=flat
|
[release-image]: https://img.shields.io/badge/release-0.21.4-green.svg?style=flat
|
||||||
[releases]: https://github.com/introlab/rtabmap/releases
|
[releases]: https://github.com/introlab/rtabmap/releases
|
||||||
|
|
||||||
[downloads-image]: https://img.shields.io/github/downloads/introlab/rtabmap/total?label=downloads
|
[downloads-image]: https://img.shields.io/github/downloads/introlab/rtabmap/total?label=downloads
|
||||||
|
|||||||
@@ -43,7 +43,11 @@ IF(@CONF_WITH_K4A@)
|
|||||||
ENDIF()
|
ENDIF()
|
||||||
|
|
||||||
IF(@CONF_WITH_DEPTH_AI@)
|
IF(@CONF_WITH_DEPTH_AI@)
|
||||||
find_dependency(depthai 2)
|
find_dependency(depthai 2.24)
|
||||||
|
ENDIF()
|
||||||
|
|
||||||
|
IF(@CONF_WITH_XVSDK@)
|
||||||
|
find_dependency(xvsdk)
|
||||||
ENDIF()
|
ENDIF()
|
||||||
|
|
||||||
IF(@CONF_WITH_OCTOMAP@)
|
IF(@CONF_WITH_OCTOMAP@)
|
||||||
@@ -93,8 +97,7 @@ endforeach()
|
|||||||
include("${CMAKE_CURRENT_LIST_DIR}/RTABMapTargets.cmake")
|
include("${CMAKE_CURRENT_LIST_DIR}/RTABMapTargets.cmake")
|
||||||
|
|
||||||
foreach(_comp ${RTABMap_FIND_COMPONENTS})
|
foreach(_comp ${RTABMap_FIND_COMPONENTS})
|
||||||
if (NOT ";${_RTABMap_supported_components};" MATCHES ";${_comp};")
|
if (NOT RTABMap_${_comp}_FOUND)
|
||||||
set(RTABMap_${_comp}_FOUND False)
|
|
||||||
if(${RTABMap_FIND_REQUIRED_${_comp}})
|
if(${RTABMap_FIND_REQUIRED_${_comp}})
|
||||||
set(RTABMap_FOUND False)
|
set(RTABMap_FOUND False)
|
||||||
set(RTABMap_NOT_FOUND_MESSAGE "Unsupported or not found required component: ${_comp}")
|
set(RTABMap_NOT_FOUND_MESSAGE "Unsupported or not found required component: ${_comp}")
|
||||||
|
|||||||
@@ -45,6 +45,7 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|||||||
@CERES@#define RTABMAP_CERES
|
@CERES@#define RTABMAP_CERES
|
||||||
@MRPT@#define RTABMAP_MRPT
|
@MRPT@#define RTABMAP_MRPT
|
||||||
@VERTIGO@#define RTABMAP_VERTIGO
|
@VERTIGO@#define RTABMAP_VERTIGO
|
||||||
|
@OPENNI@#define RTABMAP_OPENNI
|
||||||
@OPENNI2@#define RTABMAP_OPENNI2
|
@OPENNI2@#define RTABMAP_OPENNI2
|
||||||
@FREENECT@#define RTABMAP_FREENECT
|
@FREENECT@#define RTABMAP_FREENECT
|
||||||
@FREENECT2@#define RTABMAP_FREENECT2
|
@FREENECT2@#define RTABMAP_FREENECT2
|
||||||
@@ -68,6 +69,7 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|||||||
@REALSENSE2@#define RTABMAP_REALSENSE2
|
@REALSENSE2@#define RTABMAP_REALSENSE2
|
||||||
@MYNTEYE@#define RTABMAP_MYNTEYE
|
@MYNTEYE@#define RTABMAP_MYNTEYE
|
||||||
@DEPTHAI@#define RTABMAP_DEPTHAI
|
@DEPTHAI@#define RTABMAP_DEPTHAI
|
||||||
|
@XVSDK@#define RTABMAP_XVSDK
|
||||||
@OCTOMAP@#define RTABMAP_OCTOMAP
|
@OCTOMAP@#define RTABMAP_OCTOMAP
|
||||||
@GRIDMAP@#define RTABMAP_GRIDMAP
|
@GRIDMAP@#define RTABMAP_GRIDMAP
|
||||||
@CPUTSDF@#define RTABMAP_CPUTSDF
|
@CPUTSDF@#define RTABMAP_CPUTSDF
|
||||||
|
|||||||
@@ -334,11 +334,12 @@ void CameraARCore::setScreenRotationAndSize(ScreenRotation colorCameraToDisplayR
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
SensorData CameraARCore::captureImage(CameraInfo * info)
|
SensorData CameraARCore::updateDataOnRender(Transform & pose)
|
||||||
{
|
{
|
||||||
UScopeMutex lock(arSessionMutex_);
|
UScopeMutex lock(arSessionMutex_);
|
||||||
//LOGI("Capturing image...");
|
//LOGI("Capturing image...");
|
||||||
|
|
||||||
|
pose.setNull();
|
||||||
SensorData data;
|
SensorData data;
|
||||||
if(!arSession_)
|
if(!arSession_)
|
||||||
{
|
{
|
||||||
@@ -370,7 +371,7 @@ SensorData CameraARCore::captureImage(CameraInfo * info)
|
|||||||
if (geometry_changed != 0 || !uvs_initialized_) {
|
if (geometry_changed != 0 || !uvs_initialized_) {
|
||||||
ArFrame_transformCoordinates2d(
|
ArFrame_transformCoordinates2d(
|
||||||
arSession_, arFrame_, AR_COORDINATES_2D_OPENGL_NORMALIZED_DEVICE_COORDINATES,
|
arSession_, arFrame_, AR_COORDINATES_2D_OPENGL_NORMALIZED_DEVICE_COORDINATES,
|
||||||
BackgroundRenderer::kNumVertices, BackgroundRenderer_kVertices, AR_COORDINATES_2D_TEXTURE_NORMALIZED,
|
BackgroundRenderer::kNumVertices, BackgroundRenderer_kVerticesDevice, AR_COORDINATES_2D_TEXTURE_NORMALIZED,
|
||||||
transformed_uvs_);
|
transformed_uvs_);
|
||||||
UASSERT(transformed_uvs_);
|
UASSERT(transformed_uvs_);
|
||||||
uvs_initialized_ = true;
|
uvs_initialized_ = true;
|
||||||
@@ -393,7 +394,6 @@ SensorData CameraARCore::captureImage(CameraInfo * info)
|
|||||||
ArTrackingState camera_tracking_state;
|
ArTrackingState camera_tracking_state;
|
||||||
ArCamera_getTrackingState(arSession_, ar_camera, &camera_tracking_state);
|
ArCamera_getTrackingState(arSession_, ar_camera, &camera_tracking_state);
|
||||||
|
|
||||||
Transform pose;
|
|
||||||
CameraModel model;
|
CameraModel model;
|
||||||
if(camera_tracking_state == AR_TRACKING_STATE_TRACKING)
|
if(camera_tracking_state == AR_TRACKING_STATE_TRACKING)
|
||||||
{
|
{
|
||||||
@@ -401,24 +401,13 @@ SensorData CameraARCore::captureImage(CameraInfo * info)
|
|||||||
float pose_raw[7];
|
float pose_raw[7];
|
||||||
ArCamera_getPose(arSession_, ar_camera, arPose_);
|
ArCamera_getPose(arSession_, ar_camera, arPose_);
|
||||||
ArPose_getPoseRaw(arSession_, arPose_, pose_raw);
|
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]);
|
Transform poseArCore = 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;
|
poseArCore = rtabmap::rtabmap_world_T_opengl_world * poseArCore * rtabmap::opengl_world_T_rtabmap_world;
|
||||||
|
|
||||||
Transform poseArCore = pose;
|
if(poseArCore.isNull())
|
||||||
if(pose.isNull())
|
|
||||||
{
|
{
|
||||||
LOGE("CameraARCore: Pose is null");
|
LOGE("CameraARCore: Pose is null");
|
||||||
}
|
}
|
||||||
else
|
|
||||||
{
|
|
||||||
this->poseReceived(pose);
|
|
||||||
// adjust origin
|
|
||||||
if(!getOriginOffset().isNull())
|
|
||||||
{
|
|
||||||
pose = getOriginOffset() * pose;
|
|
||||||
}
|
|
||||||
info->odomPose = pose;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Get calibration parameters
|
// Get calibration parameters
|
||||||
float fx,fy, cx, cy;
|
float fx,fy, cx, cy;
|
||||||
@@ -551,6 +540,17 @@ SensorData CameraARCore::captureImage(CameraInfo * info)
|
|||||||
|
|
||||||
data = SensorData(scan, rgb, depthFromMotion_?getOcclusionImage():cv::Mat(), model, 0, stamp);
|
data = SensorData(scan, rgb, depthFromMotion_?getOcclusionImage():cv::Mat(), model, 0, stamp);
|
||||||
data.setFeatures(kpts, kpts3, cv::Mat());
|
data.setFeatures(kpts, kpts3, cv::Mat());
|
||||||
|
|
||||||
|
if(!poseArCore.isNull())
|
||||||
|
{
|
||||||
|
pose = poseArCore;
|
||||||
|
this->poseReceived(pose, stamp);
|
||||||
|
// adjust origin
|
||||||
|
if(!getOriginOffset().isNull())
|
||||||
|
{
|
||||||
|
pose = getOriginOffset() * pose;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@@ -571,134 +571,6 @@ SensorData CameraARCore::captureImage(CameraInfo * info)
|
|||||||
ArCamera_release(ar_camera);
|
ArCamera_release(ar_camera);
|
||||||
|
|
||||||
return data;
|
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 */
|
} /* namespace rtabmap */
|
||||||
|
|||||||
@@ -63,23 +63,14 @@ public:
|
|||||||
CameraARCore(void* env, void* context, void* activity, bool depthFromMotion = false, bool smoothing = false);
|
CameraARCore(void* env, void* context, void* activity, bool depthFromMotion = false, bool smoothing = false);
|
||||||
virtual ~CameraARCore();
|
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 void setScreenRotationAndSize(ScreenRotation colorCameraToDisplayRotation, int width, int height);
|
||||||
|
|
||||||
virtual bool init(const std::string & calibrationFolder = ".", const std::string & cameraName = "");
|
virtual bool init(const std::string & calibrationFolder = ".", const std::string & cameraName = "");
|
||||||
void setupGL();
|
virtual void close(); // close ARCore connection
|
||||||
virtual void close(); // close Tango connection
|
|
||||||
virtual std::string getSerial() const;
|
virtual std::string getSerial() const;
|
||||||
GLuint getTextureId() const {return textureId_;}
|
|
||||||
|
|
||||||
void imageCallback(AImageReader *reader);
|
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
virtual SensorData captureImage(CameraInfo * info = 0); // should be called in opengl thread
|
virtual SensorData updateDataOnRender(Transform & pose); // should be called in opengl thread
|
||||||
virtual void capturePoseOnly();
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
rtabmap::Transform getPoseAtTimestamp(double timestamp);
|
rtabmap::Transform getPoseAtTimestamp(double timestamp);
|
||||||
|
|||||||
@@ -117,9 +117,6 @@ bool CameraAREngine::init(const std::string & calibrationFolder, const std::stri
|
|||||||
|
|
||||||
deviceTColorCamera_ = opticalRotation;
|
deviceTColorCamera_ = opticalRotation;
|
||||||
|
|
||||||
// Required as ArSession_update does some off-screen OpenGL stuff...
|
|
||||||
HwArSession_setCameraTextureName(arSession_, textureId_);
|
|
||||||
|
|
||||||
if (HwArSession_resume(arSession_) != HWAR_SUCCESS)
|
if (HwArSession_resume(arSession_) != HWAR_SUCCESS)
|
||||||
{
|
{
|
||||||
UERROR("Cannot resume camera!");
|
UERROR("Cannot resume camera!");
|
||||||
@@ -169,38 +166,87 @@ void CameraAREngine::close()
|
|||||||
CameraMobile::close();
|
CameraMobile::close();
|
||||||
}
|
}
|
||||||
|
|
||||||
SensorData CameraAREngine::captureImage(CameraInfo * info)
|
void CameraAREngine::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;
|
||||||
|
}
|
||||||
|
|
||||||
|
HwArSession_setDisplayGeometry(arSession_, ret, width, height);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
SensorData CameraAREngine::updateDataOnRender(Transform & pose)
|
||||||
{
|
{
|
||||||
UScopeMutex lock(arSessionMutex_);
|
UScopeMutex lock(arSessionMutex_);
|
||||||
//LOGI("Capturing image...");
|
//LOGI("Capturing image...");
|
||||||
|
|
||||||
|
pose.setNull();
|
||||||
SensorData data;
|
SensorData data;
|
||||||
if(!arSession_)
|
if(!arSession_)
|
||||||
{
|
{
|
||||||
return data;
|
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)
|
||||||
|
HwArSession_setCameraTextureName(arSession_, textureId_);
|
||||||
|
|
||||||
// Update session to get current frame and render camera background.
|
// Update session to get current frame and render camera background.
|
||||||
if (HwArSession_update(arSession_, arFrame_) != HWAR_SUCCESS) {
|
if (HwArSession_update(arSession_, arFrame_) != HWAR_SUCCESS) {
|
||||||
LOGE("CameraAREngine::captureImage() ArSession_update error");
|
LOGE("CameraAREngine::captureImage() ArSession_update error");
|
||||||
return data;
|
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;
|
||||||
|
HwArFrame_getDisplayGeometryChanged(arSession_, arFrame_, &geometry_changed);
|
||||||
|
if (geometry_changed != 0 || !uvs_initialized_) {
|
||||||
|
HwArFrame_transformDisplayUvCoords(
|
||||||
|
arSession_, arFrame_,
|
||||||
|
BackgroundRenderer::kNumVertices*2, BackgroundRenderer_kVerticesView,
|
||||||
|
transformed_uvs_);
|
||||||
|
UERROR("uv: (%f,%f) (%f,%f) (%f,%f) (%f,%f)",
|
||||||
|
transformed_uvs_[0], transformed_uvs_[1],
|
||||||
|
transformed_uvs_[2], transformed_uvs_[3],
|
||||||
|
transformed_uvs_[4], transformed_uvs_[5],
|
||||||
|
transformed_uvs_[6], transformed_uvs_[7]);
|
||||||
|
UASSERT(transformed_uvs_);
|
||||||
|
uvs_initialized_ = true;
|
||||||
|
}
|
||||||
|
|
||||||
HwArCamera* ar_camera;
|
HwArCamera* ar_camera;
|
||||||
HwArFrame_acquireCamera(arSession_, arFrame_, &ar_camera);
|
HwArFrame_acquireCamera(arSession_, arFrame_, &ar_camera);
|
||||||
|
|
||||||
|
HwArCamera_getViewMatrix(arSession_, ar_camera, glm::value_ptr(viewMatrix_));
|
||||||
|
HwArCamera_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_));
|
||||||
|
}
|
||||||
|
|
||||||
HwArTrackingState camera_tracking_state;
|
HwArTrackingState camera_tracking_state;
|
||||||
HwArCamera_getTrackingState(arSession_, ar_camera, &camera_tracking_state);
|
HwArCamera_getTrackingState(arSession_, ar_camera, &camera_tracking_state);
|
||||||
|
|
||||||
Transform pose;
|
|
||||||
if(camera_tracking_state == HWAR_TRACKING_STATE_TRACKING)
|
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
|
// Get calibration parameters
|
||||||
// FIXME: Hard-coded as getting intrinsics with the api fails
|
// FIXME: Hard-coded as getting intrinsics with the api fails
|
||||||
float fx=492.689667,fy=492.606201, cx=323.594849, cy=234.659744;
|
float fx=492.689667,fy=492.606201, cx=323.594849, cy=234.659744;
|
||||||
@@ -274,6 +320,26 @@ SensorData CameraAREngine::captureImage(CameraInfo * info)
|
|||||||
double stamp = double(timestamp_ns)/10e8;
|
double stamp = double(timestamp_ns)/10e8;
|
||||||
CameraModel model = CameraModel(fx, fy, cx, cy, deviceTColorCamera_, 0, cv::Size(camWidth, camHeight));
|
CameraModel model = CameraModel(fx, fy, cx, cy, deviceTColorCamera_, 0, cv::Size(camWidth, camHeight));
|
||||||
data = SensorData(outputRGB, outputDepth, model, 0, stamp);
|
data = SensorData(outputRGB, outputDepth, model, 0, stamp);
|
||||||
|
|
||||||
|
// 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())
|
||||||
|
{
|
||||||
|
LOGE("CameraAREngine: Pose is null");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
pose = rtabmap::rtabmap_world_T_opengl_world * pose * rtabmap::opengl_world_T_rtabmap_world;
|
||||||
|
this->poseReceived(pose, stamp);
|
||||||
|
// adjust origin
|
||||||
|
if(!getOriginOffset().isNull())
|
||||||
|
{
|
||||||
|
pose = getOriginOffset() * pose;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@@ -291,66 +357,8 @@ SensorData CameraAREngine::captureImage(CameraInfo * info)
|
|||||||
}
|
}
|
||||||
|
|
||||||
HwArCamera_release(ar_camera);
|
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;
|
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 */
|
} /* namespace rtabmap */
|
||||||
|
|||||||
@@ -38,6 +38,7 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|||||||
#include <rtabmap/utilite/UEvent.h>
|
#include <rtabmap/utilite/UEvent.h>
|
||||||
#include <rtabmap/utilite/UTimer.h>
|
#include <rtabmap/utilite/UTimer.h>
|
||||||
#include <boost/thread/mutex.hpp>
|
#include <boost/thread/mutex.hpp>
|
||||||
|
#include <background_renderer.h>
|
||||||
|
|
||||||
#include <huawei_arengine_interface.h>
|
#include <huawei_arengine_interface.h>
|
||||||
|
|
||||||
@@ -48,13 +49,14 @@ public:
|
|||||||
CameraAREngine(void* env, void* context, void* activity, bool smoothing = false);
|
CameraAREngine(void* env, void* context, void* activity, bool smoothing = false);
|
||||||
virtual ~CameraAREngine();
|
virtual ~CameraAREngine();
|
||||||
|
|
||||||
|
virtual void setScreenRotationAndSize(ScreenRotation colorCameraToDisplayRotation, int width, int height);
|
||||||
|
|
||||||
virtual bool init(const std::string & calibrationFolder = ".", const std::string & cameraName = "");
|
virtual bool init(const std::string & calibrationFolder = ".", const std::string & cameraName = "");
|
||||||
virtual void close(); // close Tango connection
|
virtual void close(); // close AREngine connection
|
||||||
virtual std::string getSerial() const;
|
virtual std::string getSerial() const;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
virtual SensorData captureImage(CameraInfo * info = 0);
|
virtual SensorData updateDataOnRender(Transform & pose);
|
||||||
virtual void capturePoseOnly();
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
rtabmap::Transform getPoseAtTimestamp(double timestamp);
|
rtabmap::Transform getPoseAtTimestamp(double timestamp);
|
||||||
@@ -69,7 +71,6 @@ private:
|
|||||||
HwArCameraIntrinsics *arCameraIntrinsics_ = nullptr;
|
HwArCameraIntrinsics *arCameraIntrinsics_ = nullptr;
|
||||||
HwArPose * arPose_ = nullptr;
|
HwArPose * arPose_ = nullptr;
|
||||||
bool arInstallRequested_;
|
bool arInstallRequested_;
|
||||||
GLuint textureId_;
|
|
||||||
UMutex arSessionMutex_;
|
UMutex arSessionMutex_;
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -55,10 +55,8 @@ const rtabmap::Transform CameraMobile::opticalRotationInv = Transform(
|
|||||||
CameraMobile::CameraMobile(bool smoothing) :
|
CameraMobile::CameraMobile(bool smoothing) :
|
||||||
Camera(10),
|
Camera(10),
|
||||||
deviceTColorCamera_(Transform::getIdentity()),
|
deviceTColorCamera_(Transform::getIdentity()),
|
||||||
spinOncePreviousStamp_(0.0),
|
|
||||||
textureId_(0),
|
textureId_(0),
|
||||||
uvs_initialized_(false),
|
uvs_initialized_(false),
|
||||||
previousStamp_(0.0),
|
|
||||||
stampEpochOffset_(0.0),
|
stampEpochOffset_(0.0),
|
||||||
smoothing_(smoothing),
|
smoothing_(smoothing),
|
||||||
colorCameraToDisplayRotation_(ROTATION_0),
|
colorCameraToDisplayRotation_(ROTATION_0),
|
||||||
@@ -79,13 +77,12 @@ bool CameraMobile::init(const std::string &, const std::string &)
|
|||||||
|
|
||||||
void CameraMobile::close()
|
void CameraMobile::close()
|
||||||
{
|
{
|
||||||
previousPose_.setNull();
|
firstFrame_ = true;
|
||||||
previousStamp_ = 0.0;
|
|
||||||
lastKnownGPS_ = GPS();
|
lastKnownGPS_ = GPS();
|
||||||
lastEnvSensors_.clear();
|
lastEnvSensors_.clear();
|
||||||
originOffset_ = Transform();
|
originOffset_ = Transform();
|
||||||
originUpdate_ = false;
|
originUpdate_ = false;
|
||||||
pose_ = Transform();
|
dataPose_ = Transform();
|
||||||
data_ = SensorData();
|
data_ = SensorData();
|
||||||
|
|
||||||
if(textureId_ != 0)
|
if(textureId_ != 0)
|
||||||
@@ -97,35 +94,107 @@ void CameraMobile::close()
|
|||||||
|
|
||||||
void CameraMobile::resetOrigin()
|
void CameraMobile::resetOrigin()
|
||||||
{
|
{
|
||||||
previousPose_.setNull();
|
firstFrame_ = true;
|
||||||
previousStamp_ = 0.0;
|
|
||||||
lastKnownGPS_ = GPS();
|
lastKnownGPS_ = GPS();
|
||||||
lastEnvSensors_.clear();
|
lastEnvSensors_.clear();
|
||||||
pose_ = Transform();
|
dataPose_ = Transform();
|
||||||
data_ = SensorData();
|
data_ = SensorData();
|
||||||
originUpdate_ = true;
|
originUpdate_ = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void CameraMobile::poseReceived(const Transform & pose)
|
bool CameraMobile::getPose(double stamp, Transform & pose, cv::Mat & covariance, double maxWaitTime)
|
||||||
|
{
|
||||||
|
pose.setNull();
|
||||||
|
|
||||||
|
int maxWaitTimeMs = maxWaitTime * 1000;
|
||||||
|
|
||||||
|
// Interpolate pose
|
||||||
|
if(!poseBuffer_.empty())
|
||||||
|
{
|
||||||
|
poseMutex_.lock();
|
||||||
|
int waitTry = 0;
|
||||||
|
while(maxWaitTimeMs>0 && poseBuffer_.rbegin()->first < stamp && waitTry < maxWaitTimeMs)
|
||||||
|
{
|
||||||
|
poseMutex_.unlock();
|
||||||
|
++waitTry;
|
||||||
|
uSleep(1);
|
||||||
|
poseMutex_.lock();
|
||||||
|
}
|
||||||
|
if(poseBuffer_.rbegin()->first < stamp)
|
||||||
|
{
|
||||||
|
if(maxWaitTimeMs > 0)
|
||||||
|
{
|
||||||
|
UWARN("Could not find poses to interpolate at time %f after waiting %d ms (latest is %f)...", stamp, maxWaitTimeMs, poseBuffer_.rbegin()->first);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
UWARN("Could not find poses to interpolate at time %f (latest is %f)...", stamp, poseBuffer_.rbegin()->first);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
std::map<double, Transform>::const_iterator iterB = poseBuffer_.lower_bound(stamp);
|
||||||
|
std::map<double, Transform>::const_iterator iterA = iterB;
|
||||||
|
if(iterA != poseBuffer_.begin())
|
||||||
|
{
|
||||||
|
iterA = --iterA;
|
||||||
|
}
|
||||||
|
if(iterB == poseBuffer_.end())
|
||||||
|
{
|
||||||
|
iterB = --iterB;
|
||||||
|
}
|
||||||
|
if(iterA == iterB && stamp == iterA->first)
|
||||||
|
{
|
||||||
|
pose = iterA->second;
|
||||||
|
}
|
||||||
|
else if(stamp >= iterA->first && stamp <= iterB->first)
|
||||||
|
{
|
||||||
|
pose = iterA->second.interpolate((stamp-iterA->first) / (iterB->first-iterA->first), iterB->second);
|
||||||
|
}
|
||||||
|
else // stamp < iterA->first
|
||||||
|
{
|
||||||
|
UWARN("Could not find pose data to interpolate at time %f (earliest is %f). Are sensors synchronized?", stamp, iterA->first);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
poseMutex_.unlock();
|
||||||
|
}
|
||||||
|
return !pose.isNull();
|
||||||
|
}
|
||||||
|
|
||||||
|
void CameraMobile::poseReceived(const Transform & pose, double deviceStamp)
|
||||||
{
|
{
|
||||||
if(!pose.isNull())
|
if(!pose.isNull())
|
||||||
{
|
{
|
||||||
// send pose of the camera (without optical rotation)
|
Transform p = pose;
|
||||||
Transform p = pose*deviceTColorCamera_;
|
|
||||||
if(originUpdate_)
|
if(originUpdate_)
|
||||||
{
|
{
|
||||||
originOffset_ = p.translation().inverse();
|
originOffset_ = p.translation().inverse();
|
||||||
originUpdate_ = false;
|
originUpdate_ = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if(stampEpochOffset_ == 0.0)
|
||||||
|
{
|
||||||
|
stampEpochOffset_ = UTimer::now() - deviceStamp;
|
||||||
|
}
|
||||||
|
|
||||||
|
double epochStamp = stampEpochOffset_ + deviceStamp;
|
||||||
|
|
||||||
if(!originOffset_.isNull())
|
if(!originOffset_.isNull())
|
||||||
{
|
{
|
||||||
this->post(new PoseEvent(originOffset_*p));
|
p = originOffset_*p;
|
||||||
}
|
}
|
||||||
else
|
|
||||||
{
|
{
|
||||||
this->post(new PoseEvent(p));
|
UScopeMutex lock(poseMutex_);
|
||||||
|
poseBuffer_.insert(poseBuffer_.end(), std::make_pair(epochStamp, p));
|
||||||
|
if(poseBuffer_.size() > 1000)
|
||||||
|
{
|
||||||
|
poseBuffer_.erase(poseBuffer_.begin());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// send pose of the camera (with optical rotation)
|
||||||
|
this->post(new PoseEvent(p * deviceTColorCamera_));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -139,11 +208,20 @@ void CameraMobile::setGPS(const GPS & gps)
|
|||||||
lastKnownGPS_ = gps;
|
lastKnownGPS_ = gps;
|
||||||
}
|
}
|
||||||
|
|
||||||
void CameraMobile::setData(const SensorData & data, const Transform & pose, const glm::mat4 & viewMatrix, const glm::mat4 & projectionMatrix, const float * texCoord)
|
void CameraMobile::addEnvSensor(int type, float value)
|
||||||
{
|
{
|
||||||
LOGD("CameraMobile::setData pose=%s stamp=%f", pose.prettyPrint().c_str(), data.stamp());
|
lastEnvSensors_.insert(std::make_pair((EnvSensor::Type)type, EnvSensor((EnvSensor::Type)type, value)));
|
||||||
|
}
|
||||||
|
|
||||||
|
void CameraMobile::update(const SensorData & data, const Transform & pose, const glm::mat4 & viewMatrix, const glm::mat4 & projectionMatrix, const float * texCoord)
|
||||||
|
{
|
||||||
|
UScopeMutex lock(dataMutex_);
|
||||||
|
|
||||||
|
bool notify = !data_.isValid();
|
||||||
|
|
||||||
|
LOGD("CameraMobile::update pose=%s stamp=%f", pose.prettyPrint().c_str(), data.stamp());
|
||||||
data_ = data;
|
data_ = data;
|
||||||
pose_ = pose;
|
dataPose_ = pose;
|
||||||
|
|
||||||
viewMatrix_ = viewMatrix;
|
viewMatrix_ = viewMatrix;
|
||||||
projectionMatrix_ = projectionMatrix;
|
projectionMatrix_ = projectionMatrix;
|
||||||
@@ -151,7 +229,7 @@ void CameraMobile::setData(const SensorData & data, const Transform & pose, cons
|
|||||||
// adjust origin
|
// adjust origin
|
||||||
if(!originOffset_.isNull())
|
if(!originOffset_.isNull())
|
||||||
{
|
{
|
||||||
pose_ = originOffset_ * pose_;
|
dataPose_ = originOffset_ * dataPose_;
|
||||||
viewMatrix_ = glm::inverse(rtabmap::glmFromTransform(rtabmap::opengl_world_T_rtabmap_world * originOffset_ *rtabmap::rtabmap_world_T_opengl_world)*glm::inverse(viewMatrix_));
|
viewMatrix_ = glm::inverse(rtabmap::glmFromTransform(rtabmap::opengl_world_T_rtabmap_world * originOffset_ *rtabmap::rtabmap_world_T_opengl_world)*glm::inverse(viewMatrix_));
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -166,7 +244,7 @@ void CameraMobile::setData(const SensorData & data, const Transform & pose, cons
|
|||||||
uvs_initialized_ = true;
|
uvs_initialized_ = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
LOGD("CameraMobile::setData textureId_=%d", (int)textureId_);
|
LOGD("CameraMobile::update textureId_=%d", (int)textureId_);
|
||||||
|
|
||||||
if(textureId_ != 0 && texCoord != 0)
|
if(textureId_ != 0 && texCoord != 0)
|
||||||
{
|
{
|
||||||
@@ -193,78 +271,63 @@ void CameraMobile::setData(const SensorData & data, const Transform & pose, cons
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
void CameraMobile::addEnvSensor(int type, float value)
|
postUpdate();
|
||||||
{
|
|
||||||
lastEnvSensors_.insert(std::make_pair((EnvSensor::Type)type, EnvSensor((EnvSensor::Type)type, value)));
|
if(notify)
|
||||||
}
|
|
||||||
|
|
||||||
void CameraMobile::spinOnce()
|
|
||||||
{
|
|
||||||
if(!this->isRunning())
|
|
||||||
{
|
{
|
||||||
bool ignoreFrame = false;
|
dataReady_.release();
|
||||||
//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)
|
void CameraMobile::updateOnRender()
|
||||||
|
{
|
||||||
|
UScopeMutex lock(dataMutex_);
|
||||||
|
bool notify = !data_.isValid();
|
||||||
|
|
||||||
|
data_ = updateDataOnRender(dataPose_);
|
||||||
|
|
||||||
|
if(data_.isValid())
|
||||||
|
{
|
||||||
|
postUpdate();
|
||||||
|
|
||||||
|
if(notify)
|
||||||
{
|
{
|
||||||
spinOnceFrameRateTimer_.start();
|
dataReady_.release();
|
||||||
spinOncePreviousStamp_ = now;
|
|
||||||
mainLoop();
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
// just send pose
|
|
||||||
capturePoseOnly();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void CameraMobile::mainLoopBegin()
|
SensorData CameraMobile::updateDataOnRender(Transform & pose)
|
||||||
{
|
{
|
||||||
double t = cameraStartedTime_.elapsed();
|
LOGE("To use CameraMobile::updateOnRender(), CameraMobile::updateDataOnRender() "
|
||||||
if(t < 5.0)
|
"should be overridden by inherited classes. Returning empty data!\n");
|
||||||
{
|
return SensorData();
|
||||||
uSleep((5.0-t)*1000); // just to make sure that the camera is started
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void CameraMobile::mainLoop()
|
void CameraMobile::postUpdate()
|
||||||
{
|
{
|
||||||
CameraInfo info;
|
if(data_.isValid())
|
||||||
SensorData data = this->captureImage(&info);
|
|
||||||
|
|
||||||
if(data.isValid() && !info.odomPose.isNull())
|
|
||||||
{
|
{
|
||||||
if(lastKnownGPS_.stamp() > 0.0 && data.stamp()-lastKnownGPS_.stamp()<1.0)
|
if(lastKnownGPS_.stamp() > 0.0 && data_.stamp()-lastKnownGPS_.stamp()<1.0)
|
||||||
{
|
{
|
||||||
data.setGPS(lastKnownGPS_);
|
data_.setGPS(lastKnownGPS_);
|
||||||
}
|
}
|
||||||
else if(lastKnownGPS_.stamp()>0.0)
|
else if(lastKnownGPS_.stamp()>0.0)
|
||||||
{
|
{
|
||||||
LOGD("GPS too old (current time=%f, gps time = %f)", data.stamp(), lastKnownGPS_.stamp());
|
LOGD("GPS too old (current time=%f, gps time = %f)", data_.stamp(), lastKnownGPS_.stamp());
|
||||||
}
|
}
|
||||||
|
|
||||||
if(lastEnvSensors_.size())
|
if(lastEnvSensors_.size())
|
||||||
{
|
{
|
||||||
data.setEnvSensors(lastEnvSensors_);
|
data_.setEnvSensors(lastEnvSensors_);
|
||||||
lastEnvSensors_.clear();
|
lastEnvSensors_.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
if(smoothing_ && !data.depthRaw().empty())
|
if(smoothing_ && !data_.depthRaw().empty())
|
||||||
{
|
{
|
||||||
//UTimer t;
|
//UTimer t;
|
||||||
data.setDepthOrRightRaw(rtabmap::util2d::fastBilateralFiltering(data.depthRaw(), bilateralFilteringSigmaS, bilateralFilteringSigmaR));
|
data_.setDepthOrRightRaw(rtabmap::util2d::fastBilateralFiltering(data_.depthRaw(), bilateralFilteringSigmaS, bilateralFilteringSigmaR));
|
||||||
//LOGD("Bilateral filtering, time=%fs", t.ticks());
|
//LOGD("Bilateral filtering, time=%fs", t.ticks());
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -273,15 +336,15 @@ void CameraMobile::mainLoop()
|
|||||||
{
|
{
|
||||||
UDEBUG("ROTATION_90");
|
UDEBUG("ROTATION_90");
|
||||||
cv::Mat rgb, depth;
|
cv::Mat rgb, depth;
|
||||||
cv::Mat rgbt(data.imageRaw().cols, data.imageRaw().rows, data.imageRaw().type());
|
cv::Mat rgbt(data_.imageRaw().cols, data_.imageRaw().rows, data_.imageRaw().type());
|
||||||
cv::flip(data.imageRaw(),rgb,1);
|
cv::flip(data_.imageRaw(),rgb,1);
|
||||||
cv::transpose(rgb,rgbt);
|
cv::transpose(rgb,rgbt);
|
||||||
rgb = rgbt;
|
rgb = rgbt;
|
||||||
cv::Mat deptht(data.depthRaw().cols, data.depthRaw().rows, data.depthRaw().type());
|
cv::Mat deptht(data_.depthRaw().cols, data_.depthRaw().rows, data_.depthRaw().type());
|
||||||
cv::flip(data.depthRaw(),depth,1);
|
cv::flip(data_.depthRaw(),depth,1);
|
||||||
cv::transpose(depth,deptht);
|
cv::transpose(depth,deptht);
|
||||||
depth = deptht;
|
depth = deptht;
|
||||||
CameraModel model = data.cameraModels()[0];
|
CameraModel model = data_.cameraModels()[0];
|
||||||
cv::Size sizet(model.imageHeight(), model.imageWidth());
|
cv::Size sizet(model.imageHeight(), model.imageWidth());
|
||||||
model = CameraModel(
|
model = CameraModel(
|
||||||
model.fy(),
|
model.fy(),
|
||||||
@@ -290,25 +353,25 @@ void CameraMobile::mainLoop()
|
|||||||
model.cx()>0?model.imageWidth()-model.cx():0,
|
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.localTransform()*rtabmap::Transform(0,-1,0,0, 1,0,0,0, 0,0,1,0));
|
||||||
model.setImageSize(sizet);
|
model.setImageSize(sizet);
|
||||||
data.setRGBDImage(rgb, depth, model);
|
data_.setRGBDImage(rgb, depth, model);
|
||||||
|
|
||||||
std::vector<cv::KeyPoint> keypoints = data.keypoints();
|
std::vector<cv::KeyPoint> keypoints = data_.keypoints();
|
||||||
for(size_t i=0; i<keypoints.size(); ++i)
|
for(size_t i=0; i<keypoints.size(); ++i)
|
||||||
{
|
{
|
||||||
keypoints[i].pt.x = data.keypoints()[i].pt.y;
|
keypoints[i].pt.x = data_.keypoints()[i].pt.y;
|
||||||
keypoints[i].pt.y = rgb.rows - data.keypoints()[i].pt.x;
|
keypoints[i].pt.y = rgb.rows - data_.keypoints()[i].pt.x;
|
||||||
}
|
}
|
||||||
data.setFeatures(keypoints, data.keypoints3D(), cv::Mat());
|
data_.setFeatures(keypoints, data_.keypoints3D(), cv::Mat());
|
||||||
}
|
}
|
||||||
else if(colorCameraToDisplayRotation_ == ROTATION_180)
|
else if(colorCameraToDisplayRotation_ == ROTATION_180)
|
||||||
{
|
{
|
||||||
UDEBUG("ROTATION_180");
|
UDEBUG("ROTATION_180");
|
||||||
cv::Mat rgb, depth;
|
cv::Mat rgb, depth;
|
||||||
cv::flip(data.imageRaw(),rgb,1);
|
cv::flip(data_.imageRaw(),rgb,1);
|
||||||
cv::flip(rgb,rgb,0);
|
cv::flip(rgb,rgb,0);
|
||||||
cv::flip(data.depthOrRightRaw(),depth,1);
|
cv::flip(data_.depthOrRightRaw(),depth,1);
|
||||||
cv::flip(depth,depth,0);
|
cv::flip(depth,depth,0);
|
||||||
CameraModel model = data.cameraModels()[0];
|
CameraModel model = data_.cameraModels()[0];
|
||||||
cv::Size sizet(model.imageWidth(), model.imageHeight());
|
cv::Size sizet(model.imageWidth(), model.imageHeight());
|
||||||
model = CameraModel(
|
model = CameraModel(
|
||||||
model.fx(),
|
model.fx(),
|
||||||
@@ -317,26 +380,26 @@ void CameraMobile::mainLoop()
|
|||||||
model.cy()>0?model.imageHeight()-model.cy():0,
|
model.cy()>0?model.imageHeight()-model.cy():0,
|
||||||
model.localTransform()*rtabmap::Transform(0,0,0,0,0,1,0));
|
model.localTransform()*rtabmap::Transform(0,0,0,0,0,1,0));
|
||||||
model.setImageSize(sizet);
|
model.setImageSize(sizet);
|
||||||
data.setRGBDImage(rgb, depth, model);
|
data_.setRGBDImage(rgb, depth, model);
|
||||||
|
|
||||||
std::vector<cv::KeyPoint> keypoints = data.keypoints();
|
std::vector<cv::KeyPoint> keypoints = data_.keypoints();
|
||||||
for(size_t i=0; i<keypoints.size(); ++i)
|
for(size_t i=0; i<keypoints.size(); ++i)
|
||||||
{
|
{
|
||||||
keypoints[i].pt.x = rgb.cols - data.keypoints()[i].pt.x;
|
keypoints[i].pt.x = rgb.cols - data_.keypoints()[i].pt.x;
|
||||||
keypoints[i].pt.y = rgb.rows - data.keypoints()[i].pt.y;
|
keypoints[i].pt.y = rgb.rows - data_.keypoints()[i].pt.y;
|
||||||
}
|
}
|
||||||
data.setFeatures(keypoints, data.keypoints3D(), cv::Mat());
|
data_.setFeatures(keypoints, data_.keypoints3D(), cv::Mat());
|
||||||
}
|
}
|
||||||
else if(colorCameraToDisplayRotation_ == ROTATION_270)
|
else if(colorCameraToDisplayRotation_ == ROTATION_270)
|
||||||
{
|
{
|
||||||
UDEBUG("ROTATION_270");
|
UDEBUG("ROTATION_270");
|
||||||
cv::Mat rgb(data.imageRaw().cols, data.imageRaw().rows, data.imageRaw().type());
|
cv::Mat rgb(data_.imageRaw().cols, data_.imageRaw().rows, data_.imageRaw().type());
|
||||||
cv::transpose(data.imageRaw(),rgb);
|
cv::transpose(data_.imageRaw(),rgb);
|
||||||
cv::flip(rgb,rgb,1);
|
cv::flip(rgb,rgb,1);
|
||||||
cv::Mat depth(data.depthOrRightRaw().cols, data.depthOrRightRaw().rows, data.depthOrRightRaw().type());
|
cv::Mat depth(data_.depthOrRightRaw().cols, data_.depthOrRightRaw().rows, data_.depthOrRightRaw().type());
|
||||||
cv::transpose(data.depthOrRightRaw(),depth);
|
cv::transpose(data_.depthOrRightRaw(),depth);
|
||||||
cv::flip(depth,depth,1);
|
cv::flip(depth,depth,1);
|
||||||
CameraModel model = data.cameraModels()[0];
|
CameraModel model = data_.cameraModels()[0];
|
||||||
cv::Size sizet(model.imageHeight(), model.imageWidth());
|
cv::Size sizet(model.imageHeight(), model.imageWidth());
|
||||||
model = CameraModel(
|
model = CameraModel(
|
||||||
model.fy(),
|
model.fy(),
|
||||||
@@ -345,61 +408,54 @@ void CameraMobile::mainLoop()
|
|||||||
model.cx(),
|
model.cx(),
|
||||||
model.localTransform()*rtabmap::Transform(0,1,0,0, -1,0,0,0, 0,0,1,0));
|
model.localTransform()*rtabmap::Transform(0,1,0,0, -1,0,0,0, 0,0,1,0));
|
||||||
model.setImageSize(sizet);
|
model.setImageSize(sizet);
|
||||||
data.setRGBDImage(rgb, depth, model);
|
data_.setRGBDImage(rgb, depth, model);
|
||||||
|
|
||||||
std::vector<cv::KeyPoint> keypoints = data.keypoints();
|
std::vector<cv::KeyPoint> keypoints = data_.keypoints();
|
||||||
for(size_t i=0; i<keypoints.size(); ++i)
|
for(size_t i=0; i<keypoints.size(); ++i)
|
||||||
{
|
{
|
||||||
keypoints[i].pt.x = rgb.cols - data.keypoints()[i].pt.y;
|
keypoints[i].pt.x = rgb.cols - data_.keypoints()[i].pt.y;
|
||||||
keypoints[i].pt.y = data.keypoints()[i].pt.x;
|
keypoints[i].pt.y = data_.keypoints()[i].pt.x;
|
||||||
}
|
}
|
||||||
data.setFeatures(keypoints, data.keypoints3D(), cv::Mat());
|
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)
|
SensorData CameraMobile::captureImage(SensorCaptureInfo * info)
|
||||||
{
|
{
|
||||||
if(info)
|
SensorData data;
|
||||||
|
if(dataReady_.acquire(1, 5000))
|
||||||
{
|
{
|
||||||
info->odomPose = pose_;
|
UScopeMutex lock(dataMutex_);
|
||||||
|
data = data_;
|
||||||
|
data_ = SensorData();
|
||||||
}
|
}
|
||||||
return data_;
|
if(data.isValid())
|
||||||
|
{
|
||||||
|
data.setGroundTruth(Transform());
|
||||||
|
data.setStamp(stampEpochOffset_ + data.stamp());
|
||||||
|
|
||||||
|
if(info)
|
||||||
|
{
|
||||||
|
// linear cov = 0.0001
|
||||||
|
info->odomCovariance = cv::Mat::eye(6,6,CV_64FC1) * (firstFrame_?9999.0:0.0001);
|
||||||
|
if(!firstFrame_)
|
||||||
|
{
|
||||||
|
// angular cov = 0.000001
|
||||||
|
info->odomCovariance.at<double>(3,3) *= 0.01;
|
||||||
|
info->odomCovariance.at<double>(4,4) *= 0.01;
|
||||||
|
info->odomCovariance.at<double>(5,5) *= 0.01;
|
||||||
|
}
|
||||||
|
info->odomPose = dataPose_;
|
||||||
|
}
|
||||||
|
|
||||||
|
firstFrame_ = false;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
UWARN("CameraMobile::captureImage() invalid data!");
|
||||||
|
}
|
||||||
|
return data;
|
||||||
}
|
}
|
||||||
|
|
||||||
LaserScan CameraMobile::scanFromPointCloudData(
|
LaserScan CameraMobile::scanFromPointCloudData(
|
||||||
|
|||||||
@@ -68,7 +68,7 @@ private:
|
|||||||
Transform pose_;
|
Transform pose_;
|
||||||
};
|
};
|
||||||
|
|
||||||
class CameraMobile : public Camera, public UThread, public UEventsSender {
|
class CameraMobile : public Camera, public UEventsSender {
|
||||||
public:
|
public:
|
||||||
static const float bilateralFilteringSigmaS;
|
static const float bilateralFilteringSigmaS;
|
||||||
static const float bilateralFilteringSigmaR;
|
static const float bilateralFilteringSigmaR;
|
||||||
@@ -93,14 +93,20 @@ public:
|
|||||||
|
|
||||||
// abstract functions
|
// abstract functions
|
||||||
virtual bool init(const std::string & calibrationFolder = ".", const std::string & cameraName = "");
|
virtual bool init(const std::string & calibrationFolder = ".", const std::string & cameraName = "");
|
||||||
virtual void close(); // inherited classes should call its parent in their close().
|
virtual void close(); // inherited classes should call its parent at the end of their close().
|
||||||
virtual std::string getSerial() const {return "CameraMobile";}
|
virtual std::string getSerial() const {return "CameraMobile";}
|
||||||
|
|
||||||
|
void update(const SensorData & data, const Transform & pose, const glm::mat4 & viewMatrix, const glm::mat4 & projectionMatrix, const float * texCoord);
|
||||||
|
void updateOnRender();
|
||||||
|
|
||||||
const Transform & getOriginOffset() const {return originOffset_;} // in rtabmap frame
|
const Transform & getOriginOffset() const {return originOffset_;} // in rtabmap frame
|
||||||
void resetOrigin();
|
void resetOrigin();
|
||||||
virtual bool isCalibrated() const;
|
virtual bool isCalibrated() const;
|
||||||
|
|
||||||
void poseReceived(const Transform & pose); // in rtabmap frame
|
virtual bool odomProvided() const { return true; }
|
||||||
|
virtual bool getPose(double epochStamp, Transform & pose, cv::Mat & covariance, double maxWaitTime = 0.06); // Return pose of device in rtabmap frame (with origin offset), stamp should be epoch time
|
||||||
|
void poseReceived(const Transform & pose, double deviceStamp); // original pose of device in rtabmap frame (without origin offset), stamp of the device (may be not epoch)
|
||||||
|
double getStampEpochOffset() const {return stampEpochOffset_;}
|
||||||
|
|
||||||
const CameraModel & getCameraModel() const {return model_;}
|
const CameraModel & getCameraModel() const {return model_;}
|
||||||
const Transform & getDeviceTColorCamera() const {return deviceTColorCamera_;}
|
const Transform & getDeviceTColorCamera() const {return deviceTColorCamera_;}
|
||||||
@@ -108,10 +114,7 @@ public:
|
|||||||
virtual void setScreenRotationAndSize(ScreenRotation colorCameraToDisplayRotation, int width, int height) {colorCameraToDisplayRotation_ = colorCameraToDisplayRotation;}
|
virtual void setScreenRotationAndSize(ScreenRotation colorCameraToDisplayRotation, int width, int height) {colorCameraToDisplayRotation_ = colorCameraToDisplayRotation;}
|
||||||
void setGPS(const GPS & gps);
|
void setGPS(const GPS & gps);
|
||||||
void addEnvSensor(int type, float value);
|
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_;}
|
GLuint getTextureId() {return textureId_;}
|
||||||
bool uvsInitialized() const {return uvs_initialized_;}
|
bool uvsInitialized() const {return uvs_initialized_;}
|
||||||
const float* uvsTransformed() const {return transformed_uvs_;}
|
const float* uvsTransformed() const {return transformed_uvs_;}
|
||||||
@@ -122,17 +125,15 @@ public:
|
|||||||
const cv::Mat & getOcclusionImage(CameraModel * model=0) const {if(model)*model=occlusionModel_; return occlusionImage_; }
|
const cv::Mat & getOcclusionImage(CameraModel * model=0) const {if(model)*model=occlusionModel_; return occlusionImage_; }
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
virtual SensorData captureImage(CameraInfo * info = 0);
|
virtual SensorData updateDataOnRender(Transform & pose);
|
||||||
virtual void capturePoseOnly() {}
|
|
||||||
|
|
||||||
virtual void mainLoopBegin();
|
private:
|
||||||
virtual void mainLoop();
|
virtual SensorData captureImage(SensorCaptureInfo * info = 0);
|
||||||
|
void postUpdate(); // Should be called while being protected by dataMutex_
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
CameraModel model_; // local transform is the device to camera optical rotation in rtabmap frame
|
CameraModel model_; // local transform is the device to camera optical rotation in rtabmap frame
|
||||||
Transform deviceTColorCamera_; // device to camera optical rotation in rtabmap frame
|
Transform deviceTColorCamera_; // device to camera optical rotation in rtabmap frame
|
||||||
UTimer spinOnceFrameRateTimer_;
|
|
||||||
double spinOncePreviousStamp_;
|
|
||||||
|
|
||||||
GLuint textureId_;
|
GLuint textureId_;
|
||||||
glm::mat4 viewMatrix_;
|
glm::mat4 viewMatrix_;
|
||||||
@@ -141,9 +142,7 @@ protected:
|
|||||||
bool uvs_initialized_ = false;
|
bool uvs_initialized_ = false;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
Transform previousPose_;
|
bool firstFrame_;
|
||||||
double previousStamp_;
|
|
||||||
UTimer cameraStartedTime_;
|
|
||||||
double stampEpochOffset_;
|
double stampEpochOffset_;
|
||||||
bool smoothing_;
|
bool smoothing_;
|
||||||
ScreenRotation colorCameraToDisplayRotation_;
|
ScreenRotation colorCameraToDisplayRotation_;
|
||||||
@@ -152,8 +151,13 @@ private:
|
|||||||
Transform originOffset_;
|
Transform originOffset_;
|
||||||
bool originUpdate_;
|
bool originUpdate_;
|
||||||
|
|
||||||
|
USemaphore dataReady_;
|
||||||
|
UMutex dataMutex_;
|
||||||
SensorData data_;
|
SensorData data_;
|
||||||
Transform pose_;
|
Transform dataPose_;
|
||||||
|
|
||||||
|
UMutex poseMutex_;
|
||||||
|
std::map<double, Transform> poseBuffer_; // <stamp, Pose>
|
||||||
|
|
||||||
cv::Mat occlusionImage_;
|
cv::Mat occlusionImage_;
|
||||||
CameraModel occlusionModel_;
|
CameraModel occlusionModel_;
|
||||||
|
|||||||
@@ -101,7 +101,7 @@ void onPoseAvailableRouter(void* context, const TangoPoseData* pose)
|
|||||||
if(pose->status_code == TANGO_POSE_VALID)
|
if(pose->status_code == TANGO_POSE_VALID)
|
||||||
{
|
{
|
||||||
CameraTango* app = static_cast<CameraTango*>(context);
|
CameraTango* app = static_cast<CameraTango*>(context);
|
||||||
app->poseReceived(rtabmap_world_T_tango_world * app->tangoPoseToTransform(pose) * tango_device_T_rtabmap_world);
|
app->poseReceived(rtabmap_world_T_tango_world * app->tangoPoseToTransform(pose) * tango_device_T_rtabmap_world, pose->timestamp);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -444,7 +444,7 @@ void CameraTango::cloudReceived(const cv::Mat & cloud, double timestamp)
|
|||||||
//LOGD("Depth received! %fs (%d points)", timestamp, cloud.cols);
|
//LOGD("Depth received! %fs (%d points)", timestamp, cloud.cols);
|
||||||
|
|
||||||
UASSERT(cloud.type() == CV_32FC4);
|
UASSERT(cloud.type() == CV_32FC4);
|
||||||
boost::mutex::scoped_lock lock(dataMutex_);
|
boost::mutex::scoped_lock lock(tangoDataMutex_);
|
||||||
|
|
||||||
// From post: http://stackoverflow.com/questions/29236110/timing-issues-with-tango-image-frames
|
// From post: http://stackoverflow.com/questions/29236110/timing-issues-with-tango-image-frames
|
||||||
// "In the current version of Project Tango Tablet RGB IR camera
|
// "In the current version of Project Tango Tablet RGB IR camera
|
||||||
@@ -463,7 +463,7 @@ void CameraTango::cloudReceived(const cv::Mat & cloud, double timestamp)
|
|||||||
|
|
||||||
if(dt >= 0.0 && dt < 0.5)
|
if(dt >= 0.0 && dt < 0.5)
|
||||||
{
|
{
|
||||||
bool notify = !data_.isValid();
|
bool notify = !tangoData_.isValid();
|
||||||
|
|
||||||
cv::Mat tangoImage = tangoColor_;
|
cv::Mat tangoImage = tangoColor_;
|
||||||
cv::Mat rgb;
|
cv::Mat rgb;
|
||||||
@@ -495,7 +495,7 @@ void CameraTango::cloudReceived(const cv::Mat & cloud, double timestamp)
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
LOGE("Not supported color format : %d.", tangoColorType);
|
LOGE("Not supported color format : %d.", tangoColorType);
|
||||||
data_ = SensorData();
|
tangoData_ = SensorData();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -678,24 +678,24 @@ void CameraTango::cloudReceived(const cv::Mat & cloud, double timestamp)
|
|||||||
|
|
||||||
if(rawScanPublished_)
|
if(rawScanPublished_)
|
||||||
{
|
{
|
||||||
data_ = SensorData(LaserScan::backwardCompatibility(scan, cloud.total()/scanDownsampling, 0, scanLocalTransform), rgb, depth, model, this->getNextSeqID(), rgbStamp);
|
tangoData_ = SensorData(LaserScan::backwardCompatibility(scan, cloud.total()/scanDownsampling, 0, scanLocalTransform), rgb, depth, model, this->getNextSeqID(), rgbStamp);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
data_ = SensorData(rgb, depth, model, this->getNextSeqID(), rgbStamp);
|
tangoData_ = SensorData(rgb, depth, model, this->getNextSeqID(), rgbStamp);
|
||||||
}
|
}
|
||||||
data_.setGroundTruth(odom);
|
tangoData_.setGroundTruth(odom);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
LOGE("Could not get depth and rgb images!?!");
|
LOGE("Could not get depth and rgb images!?!");
|
||||||
data_ = SensorData();
|
tangoData_ = SensorData();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(notify)
|
if(notify)
|
||||||
{
|
{
|
||||||
dataReady_.release();
|
tangoDataReady_.release();
|
||||||
}
|
}
|
||||||
LOGD("process cloud received %fs", timer.ticks());
|
LOGD("process cloud received %fs", timer.ticks());
|
||||||
}
|
}
|
||||||
@@ -709,7 +709,7 @@ void CameraTango::rgbReceived(const cv::Mat & tangoImage, int type, double times
|
|||||||
{
|
{
|
||||||
//LOGD("RGB received! %fs", timestamp);
|
//LOGD("RGB received! %fs", timestamp);
|
||||||
|
|
||||||
boost::mutex::scoped_lock lock(dataMutex_);
|
boost::mutex::scoped_lock lock(tangoDataMutex_);
|
||||||
|
|
||||||
tangoColor_ = tangoImage.clone();
|
tangoColor_ = tangoImage.clone();
|
||||||
tangoColorStamp_ = timestamp;
|
tangoColorStamp_ = timestamp;
|
||||||
@@ -775,10 +775,11 @@ rtabmap::Transform CameraTango::getPoseAtTimestamp(double timestamp)
|
|||||||
return pose;
|
return pose;
|
||||||
}
|
}
|
||||||
|
|
||||||
SensorData CameraTango::captureImage(CameraInfo * info)
|
SensorData CameraTango::updateDataOnRender(Transform & pose)
|
||||||
{
|
{
|
||||||
//LOGI("Capturing image...");
|
//LOGI("Capturing image...");
|
||||||
|
|
||||||
|
pose.setNull();
|
||||||
if(textureId_ == 0)
|
if(textureId_ == 0)
|
||||||
{
|
{
|
||||||
glGenTextures(1, &textureId_);
|
glGenTextures(1, &textureId_);
|
||||||
@@ -797,10 +798,7 @@ SensorData CameraTango::captureImage(CameraInfo * info)
|
|||||||
|
|
||||||
if (status == TANGO_SUCCESS)
|
if (status == TANGO_SUCCESS)
|
||||||
{
|
{
|
||||||
if(info)
|
pose = getPoseAtTimestamp(video_overlay_timestamp);
|
||||||
{
|
|
||||||
info->odomPose = getPoseAtTimestamp(video_overlay_timestamp);
|
|
||||||
}
|
|
||||||
|
|
||||||
int rotation = static_cast<int>(getScreenRotation()) + 1; // remove 90deg camera rotation
|
int rotation = static_cast<int>(getScreenRotation()) + 1; // remove 90deg camera rotation
|
||||||
if (rotation > 3) {
|
if (rotation > 3) {
|
||||||
@@ -876,16 +874,13 @@ SensorData CameraTango::captureImage(CameraInfo * info)
|
|||||||
}
|
}
|
||||||
|
|
||||||
SensorData data;
|
SensorData data;
|
||||||
if(dataReady_.acquireTry(1))
|
if(tangoDataReady_.acquireTry(1))
|
||||||
{
|
{
|
||||||
boost::mutex::scoped_lock lock(dataMutex_);
|
boost::mutex::scoped_lock lock(tangoDataMutex_);
|
||||||
data = data_;
|
data = tangoData_;
|
||||||
data_ = SensorData();
|
tangoData_ = SensorData();
|
||||||
if(info)
|
pose = data.groundTruth();
|
||||||
{
|
data.setGroundTruth(Transform());
|
||||||
info->odomPose = data.groundTruth();
|
|
||||||
data.setGroundTruth(Transform());
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
return data;
|
return data;
|
||||||
|
|
||||||
|
|||||||
@@ -52,7 +52,6 @@ public:
|
|||||||
virtual void close(); // close Tango connection
|
virtual void close(); // close Tango connection
|
||||||
virtual std::string getSerial() const;
|
virtual std::string getSerial() const;
|
||||||
rtabmap::Transform tangoPoseToTransform(const TangoPoseData * tangoPose) const;
|
rtabmap::Transform tangoPoseToTransform(const TangoPoseData * tangoPose) const;
|
||||||
void setColorCamera(bool enabled) {if(!this->isRunning()) colorCamera_ = enabled;}
|
|
||||||
void setDecimation(int value) {decimation_ = value;}
|
void setDecimation(int value) {decimation_ = value;}
|
||||||
void setRawScanPublished(bool enabled) {rawScanPublished_ = enabled;}
|
void setRawScanPublished(bool enabled) {rawScanPublished_ = enabled;}
|
||||||
|
|
||||||
@@ -61,7 +60,7 @@ public:
|
|||||||
void tangoEventReceived(int type, const char * key, const char * value);
|
void tangoEventReceived(int type, const char * key, const char * value);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
virtual SensorData captureImage(CameraInfo * info = 0);
|
virtual SensorData updateDataOnRender(Transform & pose);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
rtabmap::Transform getPoseAtTimestamp(double timestamp);
|
rtabmap::Transform getPoseAtTimestamp(double timestamp);
|
||||||
@@ -71,12 +70,12 @@ private:
|
|||||||
bool colorCamera_;
|
bool colorCamera_;
|
||||||
int decimation_;
|
int decimation_;
|
||||||
bool rawScanPublished_;
|
bool rawScanPublished_;
|
||||||
SensorData data_;
|
SensorData tangoData_;
|
||||||
cv::Mat tangoColor_;
|
cv::Mat tangoColor_;
|
||||||
int tangoColorType_;
|
int tangoColorType_;
|
||||||
double tangoColorStamp_;
|
double tangoColorStamp_;
|
||||||
boost::mutex dataMutex_;
|
boost::mutex tangoDataMutex_;
|
||||||
USemaphore dataReady_;
|
USemaphore tangoDataReady_;
|
||||||
cv::Mat fisheyeRectifyMapX_;
|
cv::Mat fisheyeRectifyMapX_;
|
||||||
cv::Mat fisheyeRectifyMapY_;
|
cv::Mat fisheyeRectifyMapY_;
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -65,6 +65,7 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|||||||
#include <rtabmap/core/GainCompensator.h>
|
#include <rtabmap/core/GainCompensator.h>
|
||||||
#include <rtabmap/core/DBDriver.h>
|
#include <rtabmap/core/DBDriver.h>
|
||||||
#include <rtabmap/core/Recovery.h>
|
#include <rtabmap/core/Recovery.h>
|
||||||
|
#include <rtabmap/core/lidar/LidarVLP16.h>
|
||||||
#include <pcl/common/common.h>
|
#include <pcl/common/common.h>
|
||||||
#include <pcl/filters/extract_indices.h>
|
#include <pcl/filters/extract_indices.h>
|
||||||
#include <pcl/io/ply_io.h>
|
#include <pcl/io/ply_io.h>
|
||||||
@@ -134,6 +135,7 @@ rtabmap::ParametersMap RTABMapApp::getRtabmapParameters()
|
|||||||
parameters.insert(rtabmap::ParametersPair(rtabmap::Parameters::kRtabmapPublishLikelihood(), std::string("false")));
|
parameters.insert(rtabmap::ParametersPair(rtabmap::Parameters::kRtabmapPublishLikelihood(), std::string("false")));
|
||||||
parameters.insert(rtabmap::ParametersPair(rtabmap::Parameters::kRtabmapPublishPdf(), std::string("false")));
|
parameters.insert(rtabmap::ParametersPair(rtabmap::Parameters::kRtabmapPublishPdf(), std::string("false")));
|
||||||
parameters.insert(rtabmap::ParametersPair(rtabmap::Parameters::kRtabmapStartNewMapOnLoopClosure(), uBool2Str(!localizationMode_ && appendMode_)));
|
parameters.insert(rtabmap::ParametersPair(rtabmap::Parameters::kRtabmapStartNewMapOnLoopClosure(), uBool2Str(!localizationMode_ && appendMode_)));
|
||||||
|
parameters.insert(rtabmap::ParametersPair(rtabmap::Parameters::kRGBDAggressiveLoopThr(), "0.0"));
|
||||||
parameters.insert(rtabmap::ParametersPair(rtabmap::Parameters::kMemBinDataKept(), uBool2Str(!trajectoryMode_)));
|
parameters.insert(rtabmap::ParametersPair(rtabmap::Parameters::kMemBinDataKept(), uBool2Str(!trajectoryMode_)));
|
||||||
parameters.insert(rtabmap::ParametersPair(rtabmap::Parameters::kOptimizerIterations(), "10"));
|
parameters.insert(rtabmap::ParametersPair(rtabmap::Parameters::kOptimizerIterations(), "10"));
|
||||||
parameters.insert(rtabmap::ParametersPair(rtabmap::Parameters::kMemIncrementalMemory(), uBool2Str(!localizationMode_)));
|
parameters.insert(rtabmap::ParametersPair(rtabmap::Parameters::kMemIncrementalMemory(), uBool2Str(!localizationMode_)));
|
||||||
@@ -202,6 +204,7 @@ RTABMapApp::RTABMapApp() :
|
|||||||
#endif
|
#endif
|
||||||
cameraDriver_(0),
|
cameraDriver_(0),
|
||||||
camera_(0),
|
camera_(0),
|
||||||
|
sensorCaptureThread_(0),
|
||||||
rtabmapThread_(0),
|
rtabmapThread_(0),
|
||||||
rtabmap_(0),
|
rtabmap_(0),
|
||||||
logHandler_(0),
|
logHandler_(0),
|
||||||
@@ -216,6 +219,7 @@ RTABMapApp::RTABMapApp() :
|
|||||||
cameraColor_(true),
|
cameraColor_(true),
|
||||||
fullResolution_(false),
|
fullResolution_(false),
|
||||||
appendMode_(true),
|
appendMode_(true),
|
||||||
|
useExternalLidar_(false),
|
||||||
maxCloudDepth_(2.5),
|
maxCloudDepth_(2.5),
|
||||||
minCloudDepth_(0.0),
|
minCloudDepth_(0.0),
|
||||||
cloudDensityLevel_(1),
|
cloudDensityLevel_(1),
|
||||||
@@ -537,7 +541,7 @@ int RTABMapApp::openDatabase(const std::string & databasePath, bool databaseInMe
|
|||||||
// Voxelize and filter depending on the previous cloud?
|
// Voxelize and filter depending on the previous cloud?
|
||||||
pcl::PointCloud<pcl::PointXYZRGB>::Ptr cloud;
|
pcl::PointCloud<pcl::PointXYZRGB>::Ptr cloud;
|
||||||
pcl::IndicesPtr indices(new std::vector<int>);
|
pcl::IndicesPtr indices(new std::vector<int>);
|
||||||
if(!data.imageRaw().empty() && !data.depthRaw().empty())
|
if(!data.imageRaw().empty() && !data.depthRaw().empty() && (!useExternalLidar_ || data.laserScanRaw().isEmpty()))
|
||||||
{
|
{
|
||||||
int meshDecimation = updateMeshDecimation(data.depthRaw().cols, data.depthRaw().rows);
|
int meshDecimation = updateMeshDecimation(data.depthRaw().cols, data.depthRaw().rows);
|
||||||
|
|
||||||
@@ -885,7 +889,7 @@ bool RTABMapApp::startCamera()
|
|||||||
#endif
|
#endif
|
||||||
LOGW("startCamera() camera driver=%d", cameraDriver_);
|
LOGW("startCamera() camera driver=%d", cameraDriver_);
|
||||||
boost::mutex::scoped_lock lock(cameraMutex_);
|
boost::mutex::scoped_lock lock(cameraMutex_);
|
||||||
|
|
||||||
if(cameraDriver_ == 0) // Tango
|
if(cameraDriver_ == 0) // Tango
|
||||||
{
|
{
|
||||||
#ifdef RTABMAP_TANGO
|
#ifdef RTABMAP_TANGO
|
||||||
@@ -937,6 +941,19 @@ bool RTABMapApp::startCamera()
|
|||||||
|
|
||||||
LOGI("Start camera thread");
|
LOGI("Start camera thread");
|
||||||
cameraJustInitialized_ = true;
|
cameraJustInitialized_ = true;
|
||||||
|
if(useExternalLidar_)
|
||||||
|
{
|
||||||
|
rtabmap::LidarVLP16 * lidar = new rtabmap::LidarVLP16(boost::asio::ip::address_v4::from_string("192.168.1.201"), 2368, true);
|
||||||
|
lidar->init();
|
||||||
|
camera_->setImageRate(0); // if lidar, to get close camera synchronization
|
||||||
|
sensorCaptureThread_ = new rtabmap::SensorCaptureThread(lidar, camera_, camera_, rtabmap::Transform::getIdentity());
|
||||||
|
sensorCaptureThread_->setScanParameters(false, 1, 0.0f, 0.0f, 0.0f, 0, 0.0f, 0.0f, true);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
sensorCaptureThread_ = new rtabmap::SensorCaptureThread(camera_);
|
||||||
|
}
|
||||||
|
sensorCaptureThread_->start();
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
UERROR("Failed camera initialization!");
|
UERROR("Failed camera initialization!");
|
||||||
@@ -948,13 +965,12 @@ void RTABMapApp::stopCamera()
|
|||||||
LOGI("stopCamera()");
|
LOGI("stopCamera()");
|
||||||
{
|
{
|
||||||
boost::mutex::scoped_lock lock(cameraMutex_);
|
boost::mutex::scoped_lock lock(cameraMutex_);
|
||||||
if(camera_!=0)
|
if(sensorCaptureThread_!=0)
|
||||||
{
|
{
|
||||||
camera_->join(true);
|
sensorCaptureThread_->join(true);
|
||||||
camera_->close();
|
delete sensorCaptureThread_; // camera_ is closed and deleted inside
|
||||||
delete camera_;
|
sensorCaptureThread_ = 0;
|
||||||
camera_ = 0;
|
camera_ = 0;
|
||||||
poseBuffer_.clear();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
@@ -1241,7 +1257,7 @@ int RTABMapApp::Render()
|
|||||||
std::list<rtabmap::RtabmapEvent*> rtabmapEvents;
|
std::list<rtabmap::RtabmapEvent*> rtabmapEvents;
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
if(camera_ == 0)
|
if(sensorCaptureThread_ == 0)
|
||||||
{
|
{
|
||||||
// We are not doing continous drawing, just measure single draw
|
// We are not doing continous drawing, just measure single draw
|
||||||
fpsTime_.restart();
|
fpsTime_.restart();
|
||||||
@@ -1272,49 +1288,45 @@ int RTABMapApp::Render()
|
|||||||
{
|
{
|
||||||
if(cameraDriver_ <= 2)
|
if(cameraDriver_ <= 2)
|
||||||
{
|
{
|
||||||
camera_->spinOnce();
|
camera_->updateOnRender();
|
||||||
}
|
}
|
||||||
#ifdef DEBUG_RENDERING_PERFORMANCE
|
#ifdef DEBUG_RENDERING_PERFORMANCE
|
||||||
LOGW("Camera spinOnce %fs", time.ticks());
|
LOGW("Camera updateOnRender %fs", time.ticks());
|
||||||
#endif
|
#endif
|
||||||
|
if(main_scene_.background_renderer_ == 0 && camera_->getTextureId() != 0)
|
||||||
if(cameraDriver_ != 2)
|
|
||||||
{
|
{
|
||||||
if(main_scene_.background_renderer_ == 0 && camera_->getTextureId() != 0)
|
main_scene_.background_renderer_ = new BackgroundRenderer();
|
||||||
|
main_scene_.background_renderer_->InitializeGlContent(((rtabmap::CameraMobile*)camera_)->getTextureId(), cameraDriver_ <= 2);
|
||||||
|
}
|
||||||
|
if(camera_->uvsInitialized())
|
||||||
|
{
|
||||||
|
uvsTransformed = ((rtabmap::CameraMobile*)camera_)->uvsTransformed();
|
||||||
|
((rtabmap::CameraMobile*)camera_)->getVPMatrices(arViewMatrix, arProjectionMatrix);
|
||||||
|
if(graphOptimization_ && !mapToOdom_.isIdentity())
|
||||||
{
|
{
|
||||||
main_scene_.background_renderer_ = new BackgroundRenderer();
|
rtabmap::Transform mapCorrection = rtabmap::opengl_world_T_rtabmap_world * mapToOdom_ *rtabmap::rtabmap_world_T_opengl_world;
|
||||||
main_scene_.background_renderer_->InitializeGlContent(((rtabmap::CameraMobile*)camera_)->getTextureId(), cameraDriver_ == 0 || cameraDriver_ == 1);
|
arViewMatrix = glm::inverse(rtabmap::glmFromTransform(mapCorrection)*glm::inverse(arViewMatrix));
|
||||||
}
|
}
|
||||||
if(camera_->uvsInitialized())
|
}
|
||||||
{
|
if(!visualizingMesh_ && main_scene_.GetCameraType() == tango_gl::GestureCamera::kFirstPerson)
|
||||||
uvsTransformed = ((rtabmap::CameraMobile*)camera_)->uvsTransformed();
|
{
|
||||||
((rtabmap::CameraMobile*)camera_)->getVPMatrices(arViewMatrix, arProjectionMatrix);
|
rtabmap::CameraModel occlusionModel;
|
||||||
if(graphOptimization_ && !mapToOdom_.isIdentity())
|
cv::Mat occlusionImage = ((rtabmap::CameraMobile*)camera_)->getOcclusionImage(&occlusionModel);
|
||||||
{
|
|
||||||
rtabmap::Transform mapCorrection = rtabmap::opengl_world_T_rtabmap_world * mapToOdom_ *rtabmap::rtabmap_world_T_opengl_world;
|
|
||||||
arViewMatrix = glm::inverse(rtabmap::glmFromTransform(mapCorrection)*glm::inverse(arViewMatrix));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if(!visualizingMesh_ && main_scene_.GetCameraType() == tango_gl::GestureCamera::kFirstPerson)
|
|
||||||
{
|
|
||||||
rtabmap::CameraModel occlusionModel;
|
|
||||||
cv::Mat occlusionImage = ((rtabmap::CameraMobile*)camera_)->getOcclusionImage(&occlusionModel);
|
|
||||||
|
|
||||||
if(occlusionModel.isValidForProjection())
|
if(occlusionModel.isValidForProjection())
|
||||||
{
|
{
|
||||||
pcl::IndicesPtr indices(new std::vector<int>);
|
pcl::IndicesPtr indices(new std::vector<int>);
|
||||||
int meshDecimation = updateMeshDecimation(occlusionImage.cols, occlusionImage.rows);
|
int meshDecimation = updateMeshDecimation(occlusionImage.cols, occlusionImage.rows);
|
||||||
pcl::PointCloud<pcl::PointXYZ>::Ptr cloud = rtabmap::util3d::cloudFromDepth(occlusionImage, occlusionModel, meshDecimation, 0, 0, indices.get());
|
pcl::PointCloud<pcl::PointXYZ>::Ptr cloud = rtabmap::util3d::cloudFromDepth(occlusionImage, occlusionModel, meshDecimation, 0, 0, indices.get());
|
||||||
cloud = rtabmap::util3d::transformPointCloud(cloud, rtabmap::opengl_world_T_rtabmap_world*mapToOdom_*occlusionModel.localTransform());
|
cloud = rtabmap::util3d::transformPointCloud(cloud, rtabmap::opengl_world_T_rtabmap_world*mapToOdom_*occlusionModel.localTransform());
|
||||||
occlusionMesh.cloud.reset(new pcl::PointCloud<pcl::PointXYZRGB>());
|
occlusionMesh.cloud.reset(new pcl::PointCloud<pcl::PointXYZRGB>());
|
||||||
pcl::copyPointCloud(*cloud, *occlusionMesh.cloud);
|
pcl::copyPointCloud(*cloud, *occlusionMesh.cloud);
|
||||||
occlusionMesh.indices = indices;
|
occlusionMesh.indices = indices;
|
||||||
occlusionMesh.polygons = rtabmap::util3d::organizedFastMesh(cloud, 1.0*M_PI/180.0, false, meshTrianglePix_);
|
occlusionMesh.polygons = rtabmap::util3d::organizedFastMesh(cloud, 1.0*M_PI/180.0, false, meshTrianglePix_);
|
||||||
}
|
}
|
||||||
else if(!occlusionImage.empty())
|
else if(!occlusionImage.empty())
|
||||||
{
|
{
|
||||||
UERROR("invalid occlusionModel: %f %f %f %f %dx%d", occlusionModel.fx(), occlusionModel.fy(), occlusionModel.cx(), occlusionModel.cy(), occlusionModel.imageWidth(), occlusionModel.imageHeight());
|
UERROR("invalid occlusionModel: %f %f %f %f %dx%d", occlusionModel.fx(), occlusionModel.fy(), occlusionModel.cx(), occlusionModel.cy(), occlusionModel.imageWidth(), occlusionModel.imageHeight());
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#ifdef DEBUG_RENDERING_PERFORMANCE
|
#ifdef DEBUG_RENDERING_PERFORMANCE
|
||||||
@@ -1334,14 +1346,14 @@ int RTABMapApp::Render()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
rtabmap::OdometryEvent odomEvent;
|
rtabmap::SensorEvent sensorEvent;
|
||||||
{
|
{
|
||||||
boost::mutex::scoped_lock lock(odomMutex_);
|
boost::mutex::scoped_lock lock(sensorMutex_);
|
||||||
if(odomEvents_.size())
|
if(sensorEvents_.size())
|
||||||
{
|
{
|
||||||
LOGI("Process odom events");
|
LOGI("Process sensor events");
|
||||||
odomEvent = odomEvents_.back();
|
sensorEvent = sensorEvents_.back();
|
||||||
odomEvents_.clear();
|
sensorEvents_.clear();
|
||||||
if(cameraJustInitialized_)
|
if(cameraJustInitialized_)
|
||||||
{
|
{
|
||||||
notifyCameraStarted = true;
|
notifyCameraStarted = true;
|
||||||
@@ -1361,7 +1373,7 @@ int RTABMapApp::Render()
|
|||||||
{
|
{
|
||||||
main_scene_.SetCameraPose(rtabmap::opengl_world_T_rtabmap_world*pose*rtabmap::optical_T_opengl);
|
main_scene_.SetCameraPose(rtabmap::opengl_world_T_rtabmap_world*pose*rtabmap::optical_T_opengl);
|
||||||
}
|
}
|
||||||
if(camera_!=0 && cameraJustInitialized_)
|
if(sensorCaptureThread_!=0 && cameraJustInitialized_)
|
||||||
{
|
{
|
||||||
notifyCameraStarted = true;
|
notifyCameraStarted = true;
|
||||||
cameraJustInitialized_ = false;
|
cameraJustInitialized_ = false;
|
||||||
@@ -1562,9 +1574,9 @@ int RTABMapApp::Render()
|
|||||||
if(clearSceneOnNextRender_)
|
if(clearSceneOnNextRender_)
|
||||||
{
|
{
|
||||||
LOGI("Clearing all rendering data...");
|
LOGI("Clearing all rendering data...");
|
||||||
odomMutex_.lock();
|
sensorMutex_.lock();
|
||||||
odomEvents_.clear();
|
sensorEvents_.clear();
|
||||||
odomMutex_.unlock();
|
sensorMutex_.unlock();
|
||||||
|
|
||||||
poseMutex_.lock();
|
poseMutex_.lock();
|
||||||
poseEvents_.clear();
|
poseEvents_.clear();
|
||||||
@@ -1800,7 +1812,7 @@ int RTABMapApp::Render()
|
|||||||
// Voxelize and filter depending on the previous cloud?
|
// Voxelize and filter depending on the previous cloud?
|
||||||
pcl::PointCloud<pcl::PointXYZRGB>::Ptr cloud;
|
pcl::PointCloud<pcl::PointXYZRGB>::Ptr cloud;
|
||||||
pcl::IndicesPtr indices(new std::vector<int>);
|
pcl::IndicesPtr indices(new std::vector<int>);
|
||||||
if(!data.imageRaw().empty() && !data.depthRaw().empty())
|
if(!data.imageRaw().empty() && !data.depthRaw().empty() && (!useExternalLidar_ || data.laserScanRaw().isEmpty()))
|
||||||
{
|
{
|
||||||
int meshDecimation = updateMeshDecimation(data.depthRaw().cols, data.depthRaw().rows);
|
int meshDecimation = updateMeshDecimation(data.depthRaw().cols, data.depthRaw().rows);
|
||||||
cloud = rtabmap::util3d::cloudRGBFromSensorData(data, meshDecimation, maxCloudDepth_, minCloudDepth_, indices.get());
|
cloud = rtabmap::util3d::cloudRGBFromSensorData(data, meshDecimation, maxCloudDepth_, minCloudDepth_, indices.get());
|
||||||
@@ -2004,26 +2016,26 @@ int RTABMapApp::Render()
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
main_scene_.setCloudVisible(-1, odomCloudShown_ && !trajectoryMode_ && camera_!=0);
|
main_scene_.setCloudVisible(-1, odomCloudShown_ && !trajectoryMode_ && sensorCaptureThread_!=0);
|
||||||
|
|
||||||
//just process the last one
|
//just process the last one
|
||||||
if(!odomEvent.pose().isNull())
|
if(!sensorEvent.info().odomPose.isNull())
|
||||||
{
|
{
|
||||||
if(odomCloudShown_ && !trajectoryMode_)
|
if(odomCloudShown_ && !trajectoryMode_)
|
||||||
{
|
{
|
||||||
if((!odomEvent.data().imageRaw().empty() && !odomEvent.data().depthRaw().empty()) || !odomEvent.data().laserScanRaw().isEmpty())
|
if((!sensorEvent.data().imageRaw().empty() && !sensorEvent.data().depthRaw().empty()) || !sensorEvent.data().laserScanRaw().isEmpty())
|
||||||
{
|
{
|
||||||
pcl::PointCloud<pcl::PointXYZRGB>::Ptr cloud;
|
pcl::PointCloud<pcl::PointXYZRGB>::Ptr cloud;
|
||||||
pcl::IndicesPtr indices(new std::vector<int>);
|
pcl::IndicesPtr indices(new std::vector<int>);
|
||||||
if((!odomEvent.data().imageRaw().empty() && !odomEvent.data().depthRaw().empty()))
|
if(!sensorEvent.data().imageRaw().empty() && !sensorEvent.data().depthRaw().empty() && (!useExternalLidar_ || sensorEvent.data().laserScanRaw().isEmpty()))
|
||||||
{
|
{
|
||||||
int meshDecimation = updateMeshDecimation(odomEvent.data().depthRaw().cols, odomEvent.data().depthRaw().rows);
|
int meshDecimation = updateMeshDecimation(sensorEvent.data().depthRaw().cols, sensorEvent.data().depthRaw().rows);
|
||||||
cloud = rtabmap::util3d::cloudRGBFromSensorData(odomEvent.data(), meshDecimation, maxCloudDepth_, minCloudDepth_, indices.get());
|
cloud = rtabmap::util3d::cloudRGBFromSensorData(sensorEvent.data(), meshDecimation, maxCloudDepth_, minCloudDepth_, indices.get());
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
//scan
|
//scan
|
||||||
cloud = rtabmap::util3d::laserScanToPointCloudRGB(rtabmap::util3d::commonFiltering(odomEvent.data().laserScanRaw(), 1, minCloudDepth_, maxCloudDepth_), odomEvent.data().laserScanRaw().localTransform(), 255, 255, 255);
|
cloud = rtabmap::util3d::laserScanToPointCloudRGB(rtabmap::util3d::commonFiltering(sensorEvent.data().laserScanRaw(), 1, minCloudDepth_, maxCloudDepth_), sensorEvent.data().laserScanRaw().localTransform(), 255, 255, 255);
|
||||||
indices->resize(cloud->size());
|
indices->resize(cloud->size());
|
||||||
for(unsigned int i=0; i<cloud->size(); ++i)
|
for(unsigned int i=0; i<cloud->size(); ++i)
|
||||||
{
|
{
|
||||||
@@ -2034,10 +2046,10 @@ int RTABMapApp::Render()
|
|||||||
if(cloud->size() && indices->size())
|
if(cloud->size() && indices->size())
|
||||||
{
|
{
|
||||||
LOGI("Created odom cloud (rgb=%dx%d depth=%dx%d cloud=%dx%d)",
|
LOGI("Created odom cloud (rgb=%dx%d depth=%dx%d cloud=%dx%d)",
|
||||||
odomEvent.data().imageRaw().cols, odomEvent.data().imageRaw().rows,
|
sensorEvent.data().imageRaw().cols, sensorEvent.data().imageRaw().rows,
|
||||||
odomEvent.data().depthRaw().cols, odomEvent.data().depthRaw().rows,
|
sensorEvent.data().depthRaw().cols, sensorEvent.data().depthRaw().rows,
|
||||||
(int)cloud->width, (int)cloud->height);
|
(int)cloud->width, (int)cloud->height);
|
||||||
main_scene_.addCloud(-1, cloud, indices, rtabmap::opengl_world_T_rtabmap_world*mapToOdom_*odomEvent.pose());
|
main_scene_.addCloud(-1, cloud, indices, rtabmap::opengl_world_T_rtabmap_world*mapToOdom_*sensorEvent.info().odomPose);
|
||||||
main_scene_.setCloudVisible(-1, true);
|
main_scene_.setCloudVisible(-1, true);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@@ -2127,7 +2139,7 @@ int RTABMapApp::Render()
|
|||||||
|
|
||||||
lastPostRenderEventTime_ = UTimer::now();
|
lastPostRenderEventTime_ = UTimer::now();
|
||||||
|
|
||||||
if(camera_!=0 && lastPoseEventTime_>0.0 && UTimer::now()-lastPoseEventTime_ > 1.0)
|
if(sensorCaptureThread_!=0 && lastPoseEventTime_>0.0 && UTimer::now()-lastPoseEventTime_ > 1.0)
|
||||||
{
|
{
|
||||||
UERROR("TangoPoseEventNotReceived");
|
UERROR("TangoPoseEventNotReceived");
|
||||||
UEventsManager::post(new rtabmap::CameraInfoEvent(10, "TangoPoseEventNotReceived", uNumber2Str(UTimer::now()-lastPoseEventTime_, 6)));
|
UEventsManager::post(new rtabmap::CameraInfoEvent(10, "TangoPoseEventNotReceived", uNumber2Str(UTimer::now()-lastPoseEventTime_, 6)));
|
||||||
@@ -2319,7 +2331,7 @@ void RTABMapApp::setTrajectoryMode(bool enabled)
|
|||||||
void RTABMapApp::setGraphOptimization(bool enabled)
|
void RTABMapApp::setGraphOptimization(bool enabled)
|
||||||
{
|
{
|
||||||
graphOptimization_ = enabled;
|
graphOptimization_ = enabled;
|
||||||
if((camera_ == 0) && rtabmap_ && rtabmap_->getMemory()->getLastWorkingSignature()!=0)
|
if((sensorCaptureThread_ == 0) && rtabmap_ && rtabmap_->getMemory()->getLastWorkingSignature()!=0)
|
||||||
{
|
{
|
||||||
std::map<int, rtabmap::Transform> poses;
|
std::map<int, rtabmap::Transform> poses;
|
||||||
std::multimap<int, rtabmap::Link> links;
|
std::multimap<int, rtabmap::Link> links;
|
||||||
@@ -3709,19 +3721,12 @@ void RTABMapApp::postCameraPoseEvent(
|
|||||||
if(qx==0 && qy==0 && qz==0 && qw==0)
|
if(qx==0 && qy==0 && qz==0 && qw==0)
|
||||||
{
|
{
|
||||||
// Lost! clear buffer
|
// Lost! clear buffer
|
||||||
poseBuffer_.clear();
|
|
||||||
camera_->resetOrigin(); // we are lost, create new session on next valid frame
|
camera_->resetOrigin(); // we are lost, create new session on next valid frame
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
rtabmap::Transform pose(x,y,z,qx,qy,qz,qw);
|
rtabmap::Transform pose(x,y,z,qx,qy,qz,qw);
|
||||||
pose = rtabmap::rtabmap_world_T_opengl_world * pose * rtabmap::opengl_world_T_rtabmap_world;
|
pose = rtabmap::rtabmap_world_T_opengl_world * pose * rtabmap::opengl_world_T_rtabmap_world;
|
||||||
camera_->poseReceived(pose);
|
camera_->poseReceived(pose, stamp);
|
||||||
|
|
||||||
poseBuffer_.insert(std::make_pair(stamp, pose));
|
|
||||||
if(poseBuffer_.size() > 1000)
|
|
||||||
{
|
|
||||||
poseBuffer_.erase(poseBuffer_.begin());
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -3833,66 +3838,41 @@ void RTABMapApp::postOdometryEvent(
|
|||||||
{
|
{
|
||||||
pose = rtabmap::rtabmap_world_T_opengl_world * pose * rtabmap::opengl_world_T_rtabmap_world;
|
pose = rtabmap::rtabmap_world_T_opengl_world * pose * rtabmap::opengl_world_T_rtabmap_world;
|
||||||
|
|
||||||
|
rtabmap::Transform poseWithOriginOffset = pose;
|
||||||
|
if(!camera_->getOriginOffset().isNull())
|
||||||
|
{
|
||||||
|
poseWithOriginOffset = camera_->getOriginOffset() * pose;
|
||||||
|
}
|
||||||
|
|
||||||
// Registration depth to rgb
|
// Registration depth to rgb
|
||||||
if(!outputDepth.empty() && !depthFrame.isNull() && depth_fx!=0 && (rgbFrame != depthFrame || depthStamp!=stamp))
|
if(!outputDepth.empty() && !depthFrame.isNull() && depth_fx!=0 && (rgbFrame != depthFrame || depthStamp!=stamp))
|
||||||
{
|
{
|
||||||
UTimer time;
|
UTimer time;
|
||||||
rtabmap::Transform motion = rtabmap::Transform::getIdentity();
|
rtabmap::Transform motion = rtabmap::Transform::getIdentity();
|
||||||
if(depthStamp != stamp && !poseBuffer_.empty())
|
if(depthStamp != stamp)
|
||||||
{
|
{
|
||||||
// Interpolate pose
|
// Interpolate pose
|
||||||
if(!poseBuffer_.empty())
|
rtabmap::Transform poseDepth;
|
||||||
|
cv::Mat cov;
|
||||||
|
if(!camera_->getPose(camera_->getStampEpochOffset()+depthStamp, poseDepth, cov, 0.0))
|
||||||
|
{
|
||||||
|
UERROR("Could not find pose at depth stamp %f (epoch=%f rgb=%f)!", depthStamp, camera_->getStampEpochOffset()+depthStamp, stamp);
|
||||||
|
}
|
||||||
|
else
|
||||||
{
|
{
|
||||||
if(poseBuffer_.rbegin()->first < depthStamp)
|
|
||||||
{
|
|
||||||
UWARN("Could not find poses to interpolate at time %f (last is %f)...", depthStamp, poseBuffer_.rbegin()->first);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
std::map<double, rtabmap::Transform >::const_iterator iterB = poseBuffer_.lower_bound(depthStamp);
|
|
||||||
std::map<double, rtabmap::Transform >::const_iterator iterA = iterB;
|
|
||||||
rtabmap::Transform poseDepth;
|
|
||||||
if(iterA != poseBuffer_.begin())
|
|
||||||
{
|
|
||||||
iterA = --iterA;
|
|
||||||
}
|
|
||||||
if(iterB == poseBuffer_.end())
|
|
||||||
{
|
|
||||||
iterB = --iterB;
|
|
||||||
}
|
|
||||||
if(iterA == iterB && depthStamp == iterA->first)
|
|
||||||
{
|
|
||||||
poseDepth = iterA->second;
|
|
||||||
}
|
|
||||||
else if(depthStamp >= iterA->first && depthStamp <= iterB->first)
|
|
||||||
{
|
|
||||||
poseDepth = iterA->second.interpolate((depthStamp-iterA->first) / (iterB->first-iterA->first), iterB->second);
|
|
||||||
}
|
|
||||||
else if(depthStamp < iterA->first)
|
|
||||||
{
|
|
||||||
UERROR("Could not find poses to interpolate at image time %f (earliest is %f). Are sensors synchronized?", depthStamp, iterA->first);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
UERROR("Could not find poses to interpolate at image time %f (between %f and %f), Are sensors synchronized?", depthStamp, iterA->first, iterB->first);
|
|
||||||
}
|
|
||||||
if(!poseDepth.isNull())
|
|
||||||
{
|
|
||||||
#ifndef DISABLE_LOG
|
#ifndef DISABLE_LOG
|
||||||
UDEBUG("poseRGB =%s (stamp=%f)", pose.prettyPrint().c_str(), depthStamp);
|
UDEBUG("poseRGB =%s (stamp=%f)", poseWithOriginOffset.prettyPrint().c_str(), stamp);
|
||||||
UDEBUG("poseDepth=%s (stamp=%f)", poseDepth.prettyPrint().c_str(), depthStamp);
|
UDEBUG("poseDepth=%s (stamp=%f)", poseDepth.prettyPrint().c_str(), depthStamp);
|
||||||
#endif
|
#endif
|
||||||
motion = pose.inverse()*poseDepth;
|
motion = poseWithOriginOffset.inverse()*poseDepth;
|
||||||
// transform in camera frame
|
// transform in camera frame
|
||||||
#ifndef DISABLE_LOG
|
#ifndef DISABLE_LOG
|
||||||
UDEBUG("motion=%s", motion.prettyPrint().c_str());
|
UDEBUG("motion=%s", motion.prettyPrint().c_str());
|
||||||
#endif
|
#endif
|
||||||
motion = rtabmap::CameraModel::opticalRotation().inverse() * motion * rtabmap::CameraModel::opticalRotation();
|
motion = rtabmap::CameraModel::opticalRotation().inverse() * motion * rtabmap::CameraModel::opticalRotation();
|
||||||
#ifndef DISABLE_LOG
|
#ifndef DISABLE_LOG
|
||||||
UDEBUG("motion=%s", motion.prettyPrint().c_str());
|
UDEBUG("motion=%s", motion.prettyPrint().c_str());
|
||||||
#endif
|
#endif
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
rtabmap::Transform rgbToDepth = motion*rgbFrame.inverse()*depthFrame;
|
rtabmap::Transform rgbToDepth = motion*rgbFrame.inverse()*depthFrame;
|
||||||
@@ -3941,11 +3921,6 @@ void RTABMapApp::postOdometryEvent(
|
|||||||
|
|
||||||
if(!outputDepth.empty())
|
if(!outputDepth.empty())
|
||||||
{
|
{
|
||||||
rtabmap::Transform poseWithOriginOffset = pose;
|
|
||||||
if(!camera_->getOriginOffset().isNull())
|
|
||||||
{
|
|
||||||
poseWithOriginOffset = camera_->getOriginOffset() * pose;
|
|
||||||
}
|
|
||||||
rtabmap::CameraModel depthModel = model.scaled(float(outputDepth.cols) / float(model.imageWidth()));
|
rtabmap::CameraModel depthModel = model.scaled(float(outputDepth.cols) / float(model.imageWidth()));
|
||||||
depthModel.setLocalTransform(poseWithOriginOffset*model.localTransform());
|
depthModel.setLocalTransform(poseWithOriginOffset*model.localTransform());
|
||||||
camera_->setOcclusionImage(outputDepth, depthModel);
|
camera_->setOcclusionImage(outputDepth, depthModel);
|
||||||
@@ -3971,8 +3946,7 @@ void RTABMapApp::postOdometryEvent(
|
|||||||
texCoords[5] = t5;
|
texCoords[5] = t5;
|
||||||
texCoords[6] = t6;
|
texCoords[6] = t6;
|
||||||
texCoords[7] = t7;
|
texCoords[7] = t7;
|
||||||
camera_->setData(data, pose, viewMatrixMat, projectionMatrix, main_scene_.GetCameraType() == tango_gl::GestureCamera::kFirstPerson?texCoords:0);
|
camera_->update(data, pose, viewMatrixMat, projectionMatrix, main_scene_.GetCameraType() == tango_gl::GestureCamera::kFirstPerson?texCoords:0);
|
||||||
camera_->spinOnce();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -3989,17 +3963,17 @@ void RTABMapApp::postOdometryEvent(
|
|||||||
|
|
||||||
bool RTABMapApp::handleEvent(UEvent * event)
|
bool RTABMapApp::handleEvent(UEvent * event)
|
||||||
{
|
{
|
||||||
if(camera_!=0)
|
if(sensorCaptureThread_!=0)
|
||||||
{
|
{
|
||||||
// called from events manager thread, so protect the data
|
// called from events manager thread, so protect the data
|
||||||
if(event->getClassName().compare("OdometryEvent") == 0)
|
if(event->getClassName().compare("SensorEvent") == 0)
|
||||||
{
|
{
|
||||||
LOGI("Received OdometryEvent!");
|
LOGI("Received SensorEvent!");
|
||||||
if(odomMutex_.try_lock())
|
if(sensorMutex_.try_lock())
|
||||||
{
|
{
|
||||||
odomEvents_.clear();
|
sensorEvents_.clear();
|
||||||
odomEvents_.push_back(*((rtabmap::OdometryEvent*)(event)));
|
sensorEvents_.push_back(*((rtabmap::SensorEvent*)(event)));
|
||||||
odomMutex_.unlock();
|
sensorMutex_.unlock();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if(event->getClassName().compare("RtabmapEvent") == 0)
|
if(event->getClassName().compare("RtabmapEvent") == 0)
|
||||||
|
|||||||
@@ -40,7 +40,9 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|||||||
#include "util.h"
|
#include "util.h"
|
||||||
#include "ProgressionStatus.h"
|
#include "ProgressionStatus.h"
|
||||||
|
|
||||||
|
#include <rtabmap/core/SensorCaptureThread.h>
|
||||||
#include <rtabmap/core/RtabmapThread.h>
|
#include <rtabmap/core/RtabmapThread.h>
|
||||||
|
#include <rtabmap/core/SensorEvent.h>
|
||||||
#include <rtabmap/utilite/UEventsHandler.h>
|
#include <rtabmap/utilite/UEventsHandler.h>
|
||||||
#include <boost/thread/mutex.hpp>
|
#include <boost/thread/mutex.hpp>
|
||||||
#include <pcl/pcl_base.h>
|
#include <pcl/pcl_base.h>
|
||||||
@@ -209,6 +211,7 @@ class RTABMapApp : public UEventsHandler {
|
|||||||
private:
|
private:
|
||||||
int cameraDriver_;
|
int cameraDriver_;
|
||||||
rtabmap::CameraMobile * camera_;
|
rtabmap::CameraMobile * camera_;
|
||||||
|
rtabmap::SensorCaptureThread * sensorCaptureThread_;
|
||||||
rtabmap::RtabmapThread * rtabmapThread_;
|
rtabmap::RtabmapThread * rtabmapThread_;
|
||||||
rtabmap::Rtabmap * rtabmap_;
|
rtabmap::Rtabmap * rtabmap_;
|
||||||
rtabmap::LogHandler * logHandler_;
|
rtabmap::LogHandler * logHandler_;
|
||||||
@@ -224,6 +227,7 @@ class RTABMapApp : public UEventsHandler {
|
|||||||
bool cameraColor_;
|
bool cameraColor_;
|
||||||
bool fullResolution_;
|
bool fullResolution_;
|
||||||
bool appendMode_;
|
bool appendMode_;
|
||||||
|
bool useExternalLidar_;
|
||||||
float maxCloudDepth_;
|
float maxCloudDepth_;
|
||||||
float minCloudDepth_;
|
float minCloudDepth_;
|
||||||
int cloudDensityLevel_;
|
int cloudDensityLevel_;
|
||||||
@@ -270,16 +274,15 @@ class RTABMapApp : public UEventsHandler {
|
|||||||
UTimer fpsTime_;
|
UTimer fpsTime_;
|
||||||
|
|
||||||
std::list<rtabmap::RtabmapEvent*> rtabmapEvents_;
|
std::list<rtabmap::RtabmapEvent*> rtabmapEvents_;
|
||||||
std::list<rtabmap::OdometryEvent> odomEvents_;
|
std::list<rtabmap::SensorEvent> sensorEvents_;
|
||||||
std::list<rtabmap::Transform> poseEvents_;
|
std::list<rtabmap::Transform> poseEvents_;
|
||||||
std::map<double, rtabmap::Transform> poseBuffer_;
|
|
||||||
|
|
||||||
rtabmap::Transform mapToOdom_;
|
rtabmap::Transform mapToOdom_;
|
||||||
|
|
||||||
boost::mutex cameraMutex_;
|
boost::mutex cameraMutex_;
|
||||||
boost::mutex rtabmapMutex_;
|
boost::mutex rtabmapMutex_;
|
||||||
boost::mutex meshesMutex_;
|
boost::mutex meshesMutex_;
|
||||||
boost::mutex odomMutex_;
|
boost::mutex sensorMutex_;
|
||||||
boost::mutex poseMutex_;
|
boost::mutex poseMutex_;
|
||||||
boost::mutex renderingMutex_;
|
boost::mutex renderingMutex_;
|
||||||
|
|
||||||
|
|||||||
@@ -155,7 +155,7 @@ void BackgroundRenderer::InitializeGlContent(GLuint textureId, bool oes)
|
|||||||
}
|
}
|
||||||
|
|
||||||
void BackgroundRenderer::Draw(const float * transformed_uvs, const GLuint & depthTexture, int screenWidth, int screenHeight, bool redUnknown) {
|
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");
|
static_assert(std::extent<decltype(BackgroundRenderer_kVerticesDevice)>::value == kNumVertices * 2, "Incorrect kVertices length");
|
||||||
|
|
||||||
GLuint program = shaderPrograms_[depthTexture>0?1:0];
|
GLuint program = shaderPrograms_[depthTexture>0?1:0];
|
||||||
|
|
||||||
@@ -170,7 +170,7 @@ void BackgroundRenderer::Draw(const float * transformed_uvs, const GLuint & dept
|
|||||||
else
|
else
|
||||||
#endif
|
#endif
|
||||||
glBindTexture(GL_TEXTURE_2D, texture_id_);
|
glBindTexture(GL_TEXTURE_2D, texture_id_);
|
||||||
|
|
||||||
if(depthTexture>0)
|
if(depthTexture>0)
|
||||||
{
|
{
|
||||||
// Texture activate unit 1
|
// Texture activate unit 1
|
||||||
@@ -191,7 +191,7 @@ void BackgroundRenderer::Draw(const float * transformed_uvs, const GLuint & dept
|
|||||||
GLuint attributeVertices = glGetAttribLocation(program, "a_Position");
|
GLuint attributeVertices = glGetAttribLocation(program, "a_Position");
|
||||||
GLuint attributeUvs = glGetAttribLocation(program, "a_TexCoord");
|
GLuint attributeUvs = glGetAttribLocation(program, "a_TexCoord");
|
||||||
|
|
||||||
glVertexAttribPointer(attributeVertices, 2, GL_FLOAT, GL_FALSE, 0, BackgroundRenderer_kVertices);
|
glVertexAttribPointer(attributeVertices, 2, GL_FLOAT, GL_FALSE, 0, BackgroundRenderer_kVerticesDevice);
|
||||||
glVertexAttribPointer(attributeUvs, 2, GL_FLOAT, GL_FALSE, 0, transformed_uvs?transformed_uvs:BackgroundRenderer_kTexCoord);
|
glVertexAttribPointer(attributeUvs, 2, GL_FLOAT, GL_FALSE, 0, transformed_uvs?transformed_uvs:BackgroundRenderer_kTexCoord);
|
||||||
|
|
||||||
glEnableVertexAttribArray(attributeVertices);
|
glEnableVertexAttribArray(attributeVertices);
|
||||||
|
|||||||
@@ -28,9 +28,15 @@
|
|||||||
|
|
||||||
#include "util.h"
|
#include "util.h"
|
||||||
|
|
||||||
static const GLfloat BackgroundRenderer_kVertices[] = {
|
static const GLfloat BackgroundRenderer_kVerticesDevice[] = {
|
||||||
-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,
|
||||||
};
|
};
|
||||||
|
//static const GLfloat BackgroundRenderer_kVerticesView[] = {
|
||||||
|
// 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 1.0f, 1.0f, 1.0f,
|
||||||
|
//};
|
||||||
|
static const GLfloat BackgroundRenderer_kVerticesView[] = {
|
||||||
|
0.0f, 1.0f, 1.0f, 1.0f, 0.0f, 0.0f, 1.0f, 0.0f,
|
||||||
|
};
|
||||||
static const GLfloat BackgroundRenderer_kTexCoord[] = {
|
static const GLfloat BackgroundRenderer_kTexCoord[] = {
|
||||||
1.0f, 1.0f, 1.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f,
|
1.0f, 1.0f, 1.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f,
|
||||||
};
|
};
|
||||||
|
|||||||
5
app/android/libs/.gitignore
vendored
5
app/android/libs/.gitignore
vendored
@@ -1 +1,4 @@
|
|||||||
*.jar
|
# Ignore everything in this directory
|
||||||
|
*
|
||||||
|
# Except this file
|
||||||
|
!.gitignore
|
||||||
@@ -84,7 +84,7 @@
|
|||||||
<string name="pref_key_depth_from_motion">pref_key_depth_from_motion</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_default_depth_from_motion">false</string>
|
||||||
<string name="pref_key_arcore_localization_filtering_speed">pref_key_arcore_localization_filtering_speed</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_default_arcore_localization_filtering_speed">0</string>
|
||||||
<string name="pref_key_update_rate">pref_key_update_rate</string>
|
<string name="pref_key_update_rate">pref_key_update_rate</string>
|
||||||
<string name="pref_default_update_rate">1</string>
|
<string name="pref_default_update_rate">1</string>
|
||||||
<string name="pref_key_max_speed">pref_key_max_speed</string>
|
<string name="pref_key_max_speed">pref_key_max_speed</string>
|
||||||
|
|||||||
@@ -115,6 +115,9 @@ public class ARCoreSharedCamera {
|
|||||||
// Image reader that continuously processes CPU images.
|
// Image reader that continuously processes CPU images.
|
||||||
public TOF_ImageReader mTOFImageReader = new TOF_ImageReader();
|
public TOF_ImageReader mTOFImageReader = new TOF_ImageReader();
|
||||||
private boolean mTOFAvailable = false;
|
private boolean mTOFAvailable = false;
|
||||||
|
|
||||||
|
ByteBuffer mPreviousDepth = null;
|
||||||
|
double mPreviousDepthStamp = 0.0;
|
||||||
|
|
||||||
public boolean isDepthSupported() {return mTOFAvailable;}
|
public boolean isDepthSupported() {return mTOFAvailable;}
|
||||||
|
|
||||||
@@ -698,6 +701,7 @@ public class ARCoreSharedCamera {
|
|||||||
mToast.setText(msg);
|
mToast.setText(msg);
|
||||||
}
|
}
|
||||||
previousAnchorPose = null;
|
previousAnchorPose = null;
|
||||||
|
arCoreCorrection = Pose.IDENTITY;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
@@ -718,7 +722,8 @@ public class ARCoreSharedCamera {
|
|||||||
final double speed = Math.sqrt(t[0]*t[0]+t[1]*t[1]+t[2]*t[2])/((double)(frame.getTimestamp()-previousAnchorTimeStamp)/10e8);
|
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)
|
if(speed>=mARCoreLocalizationFilteringSpeed)
|
||||||
{
|
{
|
||||||
arCoreCorrection = arCoreCorrection.compose(previousAnchorPose).compose(pose.inverse());
|
// Only correct the translation to not lose rotation aligned with gravity
|
||||||
|
arCoreCorrection = arCoreCorrection.compose(previousAnchorPose.compose(pose.inverse()).extractTranslation());
|
||||||
t = arCoreCorrection.getTranslation();
|
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]));
|
Log.e(TAG, String.format("POTENTIAL TELEPORTATION!!!!!!!!!!!!!! previous anchor moved (speed=%f), new arcorrection: %f %f %f", speed, t[0], t[1], t[2]));
|
||||||
|
|
||||||
@@ -744,7 +749,6 @@ public class ARCoreSharedCamera {
|
|||||||
{
|
{
|
||||||
mToast.setText(msg);
|
mToast.setText(msg);
|
||||||
}
|
}
|
||||||
previousAnchorPose = null;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
@@ -755,9 +759,8 @@ public class ARCoreSharedCamera {
|
|||||||
previousAnchorTimeStamp = frame.getTimestamp();
|
previousAnchorTimeStamp = frame.getTimestamp();
|
||||||
|
|
||||||
double stamp = (double)frame.getTimestamp()/10e8;
|
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));
|
if(!RTABMapActivity.DISABLE_LOG) Log.d(TAG, String.format("pose=%f %f %f arcore %f %f %f cor= %f %f %f stamp=%f", odomPose.tx(), odomPose.ty(), odomPose.tz(), pose.tx(), pose.ty(), pose.tz(), arCoreCorrection.tx(), arCoreCorrection.ty(), arCoreCorrection.tz(), stamp));
|
||||||
RTABMapLib.postCameraPoseEvent(RTABMapActivity.nativeApplication, 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();
|
CameraIntrinsics intrinsics = camera.getImageIntrinsics();
|
||||||
try{
|
try{
|
||||||
Image image = frame.acquireCameraImage();
|
Image image = frame.acquireCameraImage();
|
||||||
@@ -813,6 +816,12 @@ public class ARCoreSharedCamera {
|
|||||||
depth = mTOFImageReader.depth16_raw;
|
depth = mTOFImageReader.depth16_raw;
|
||||||
depthStamp = (double)mTOFImageReader.timestamp/10e8;
|
depthStamp = (double)mTOFImageReader.timestamp/10e8;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if(mPreviousDepth == null)
|
||||||
|
{
|
||||||
|
mPreviousDepth = depth;
|
||||||
|
mPreviousDepthStamp = depthStamp;
|
||||||
|
}
|
||||||
|
|
||||||
if(!RTABMapActivity.DISABLE_LOG) Log.d(TAG, String.format("Depth %dx%d len=%dbytes format=%d stamp=%f",
|
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));
|
mTOFImageReader.WIDTH, mTOFImageReader.HEIGHT, depth.limit(), ImageFormat.DEPTH16, depthStamp));
|
||||||
@@ -825,13 +834,17 @@ public class ARCoreSharedCamera {
|
|||||||
rgbExtrinsics.tx(), rgbExtrinsics.ty(), rgbExtrinsics.tz(), rgbExtrinsics.qx(), rgbExtrinsics.qy(), rgbExtrinsics.qz(), rgbExtrinsics.qw(),
|
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(),
|
depthExtrinsics.tx(), depthExtrinsics.ty(), depthExtrinsics.tz(), depthExtrinsics.qx(), depthExtrinsics.qy(), depthExtrinsics.qz(), depthExtrinsics.qw(),
|
||||||
stamp,
|
stamp,
|
||||||
depthStamp,
|
depthStamp>stamp?mPreviousDepthStamp:depthStamp,
|
||||||
y, u, v, y.limit(), image.getWidth(), image.getHeight(), image.getFormat(),
|
y, u, v, y.limit(), image.getWidth(), image.getHeight(), image.getFormat(),
|
||||||
depth, depth.limit(), mTOFImageReader.WIDTH, mTOFImageReader.HEIGHT, ImageFormat.DEPTH16,
|
depthStamp>stamp?mPreviousDepth:depth, depthStamp>stamp?mPreviousDepth.limit():depth.limit(), mTOFImageReader.WIDTH, mTOFImageReader.HEIGHT, ImageFormat.DEPTH16,
|
||||||
points, points.limit()/4,
|
points, points.limit()/4,
|
||||||
viewMatrix[12], viewMatrix[13], viewMatrix[14], quat[1], quat[2], quat[3], quat[0],
|
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],
|
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]);
|
texCoord[0],texCoord[1],texCoord[2],texCoord[3],texCoord[4],texCoord[5],texCoord[6],texCoord[7]);
|
||||||
|
|
||||||
|
|
||||||
|
mPreviousDepthStamp = depthStamp;
|
||||||
|
mPreviousDepth = depth;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -284,11 +284,11 @@ void setCameraNative(const void *object, int type) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void postCameraPoseEventNative(const void *object,
|
void postCameraPoseEventNative(const void *object,
|
||||||
float x, float y, float z, float qx, float qy, float qz, float qw)
|
float x, float y, float z, float qx, float qy, float qz, float qw, double stamp)
|
||||||
{
|
{
|
||||||
if(object)
|
if(object)
|
||||||
{
|
{
|
||||||
native(object)->postCameraPoseEvent(x,y,z,qx,qy,qz,qw,0.0);
|
native(object)->postCameraPoseEvent(x,y,z,qx,qy,qz,qw,stamp);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -67,7 +67,7 @@ bool startCameraNative(const void *object);
|
|||||||
void stopCameraNative(const void *object);
|
void stopCameraNative(const void *object);
|
||||||
void setCameraNative(const void *object, int type);
|
void setCameraNative(const void *object, int type);
|
||||||
void postCameraPoseEventNative(const void *object,
|
void postCameraPoseEventNative(const void *object,
|
||||||
float x, float y, float z, float qx, float qy, float qz, float qw);
|
float x, float y, float z, float qx, float qy, float qz, float qw, double stamp);
|
||||||
void postOdometryEventNative(const void *object,
|
void postOdometryEventNative(const void *object,
|
||||||
float x, float y, float z, float qx, float qy, float qz, float qw,
|
float x, float y, float z, float qx, float qy, float qz, float qw,
|
||||||
float fx, float fy, float cx, float cy,
|
float fx, float fy, float cx, float cy,
|
||||||
|
|||||||
@@ -216,18 +216,18 @@ class RTABMap {
|
|||||||
setCameraNative(native_rtabmap, Int32(type))
|
setCameraNative(native_rtabmap, Int32(type))
|
||||||
}
|
}
|
||||||
|
|
||||||
func postCameraPoseEvent(pose: simd_float4x4) {
|
func postCameraPoseEvent(pose: simd_float4x4, stamp: TimeInterval) {
|
||||||
let rotation = GLKMatrix3(
|
let rotation = GLKMatrix3(
|
||||||
m: (pose[0,0], pose[0,1], pose[0,2],
|
m: (pose[0,0], pose[0,1], pose[0,2],
|
||||||
pose[1,0], pose[1,1], pose[1,2],
|
pose[1,0], pose[1,1], pose[1,2],
|
||||||
pose[2,0], pose[2,1], pose[2,2]))
|
pose[2,0], pose[2,1], pose[2,2]))
|
||||||
let quat = GLKQuaternionMakeWithMatrix3(rotation)
|
let quat = GLKQuaternionMakeWithMatrix3(rotation)
|
||||||
postCameraPoseEventNative(native_rtabmap, pose[3,0], pose[3,1], pose[3,2], quat.x, quat.y, quat.z, quat.w)
|
postCameraPoseEventNative(native_rtabmap, pose[3,0], pose[3,1], pose[3,2], quat.x, quat.y, quat.z, quat.w, stamp)
|
||||||
}
|
}
|
||||||
|
|
||||||
func notifyLost() {
|
func notifyLost() {
|
||||||
// a null transform will make rtabmap creating a new session
|
// a null transform will make rtabmap creating a new session
|
||||||
postCameraPoseEventNative(native_rtabmap, 0,0,0,0,0,0,0)
|
postCameraPoseEventNative(native_rtabmap, 0,0,0,0,0,0,0,0)
|
||||||
}
|
}
|
||||||
|
|
||||||
func postOdometryEvent(frame: ARFrame, orientation: UIInterfaceOrientation, viewport: CGSize) {
|
func postOdometryEvent(frame: ARFrame, orientation: UIInterfaceOrientation, viewport: CGSize) {
|
||||||
@@ -239,7 +239,7 @@ class RTABMap {
|
|||||||
|
|
||||||
let quat = GLKQuaternionMakeWithMatrix3(rotation)
|
let quat = GLKQuaternionMakeWithMatrix3(rotation)
|
||||||
|
|
||||||
postCameraPoseEventNative(native_rtabmap, pose[3,0], pose[3,1], pose[3,2], quat.x, quat.y, quat.z, quat.w)
|
postCameraPoseEventNative(native_rtabmap, pose[3,0], pose[3,1], pose[3,2], quat.x, quat.y, quat.z, quat.w, frame.timestamp)
|
||||||
|
|
||||||
let confMap = frame.sceneDepth?.confidenceMap
|
let confMap = frame.sceneDepth?.confidenceMap
|
||||||
let depthMap = frame.sceneDepth?.depthMap
|
let depthMap = frame.sceneDepth?.depthMap
|
||||||
|
|||||||
@@ -65,15 +65,18 @@ ENDIF(APPLE AND BUILD_AS_BUNDLE)
|
|||||||
|
|
||||||
IF(BUILD_AS_BUNDLE AND (APPLE OR WIN32))
|
IF(BUILD_AS_BUNDLE AND (APPLE OR WIN32))
|
||||||
SET(APPS "\$ENV{DESTDIR}\${CMAKE_INSTALL_PREFIX}/bin/${PROJECT_NAME}${CMAKE_EXECUTABLE_SUFFIX}")
|
SET(APPS "\$ENV{DESTDIR}\${CMAKE_INSTALL_PREFIX}/bin/${PROJECT_NAME}${CMAKE_EXECUTABLE_SUFFIX}")
|
||||||
SET(plugin_dest_dir bin)
|
SET(plugin_dest_dir bin/plugins)
|
||||||
SET(qtconf_dest_dir bin)
|
SET(qtconf_dest_dir bin)
|
||||||
SET(openni2_dest_dir bin)
|
SET(thirdparty_dest_dir bin)
|
||||||
|
|
||||||
IF(APPLE)
|
IF(APPLE)
|
||||||
SET(plugin_dest_dir MacOS)
|
SET(plugin_dest_dir MacOS/plugins)
|
||||||
|
IF(Qt6_FOUND)
|
||||||
|
SET(plugin_dest_dir PlugIns)
|
||||||
|
ENDIF()
|
||||||
SET(qtconf_dest_dir Resources)
|
SET(qtconf_dest_dir Resources)
|
||||||
SET(openni2_dest_dir MacOS)
|
SET(thirdparty_dest_dir MacOS)
|
||||||
SET(APPS "\$ENV{DESTDIR}\${CMAKE_INSTALL_PREFIX}/MacOS/${CMAKE_BUNDLE_NAME}")
|
SET(APPS "\$ENV{DESTDIR}\${CMAKE_INSTALL_PREFIX}/MacOS/${CMAKE_BUNDLE_NAME}")
|
||||||
ENDIF(APPLE)
|
ENDIF(APPLE)
|
||||||
|
|
||||||
IF(OpenNI2_FOUND)
|
IF(OpenNI2_FOUND)
|
||||||
@@ -89,11 +92,11 @@ IF(BUILD_AS_BUNDLE AND (APPLE OR WIN32))
|
|||||||
ENDIF()
|
ENDIF()
|
||||||
|
|
||||||
INSTALL(DIRECTORY "${OpenNI2_BIN_DIR}/OpenNI2"
|
INSTALL(DIRECTORY "${OpenNI2_BIN_DIR}/OpenNI2"
|
||||||
DESTINATION ${openni2_dest_dir}
|
DESTINATION ${thirdparty_dest_dir}
|
||||||
COMPONENT runtime
|
COMPONENT runtime
|
||||||
REGEX ".*pdb" EXCLUDE)
|
REGEX ".*pdb" EXCLUDE)
|
||||||
INSTALL(FILES "${OpenNI2_BIN_DIR}/OpenNI.ini"
|
INSTALL(FILES "${OpenNI2_BIN_DIR}/OpenNI.ini"
|
||||||
DESTINATION ${openni2_dest_dir}
|
DESTINATION ${thirdparty_dest_dir}
|
||||||
COMPONENT runtime)
|
COMPONENT runtime)
|
||||||
ENDIF(OpenNI2_FOUND)
|
ENDIF(OpenNI2_FOUND)
|
||||||
|
|
||||||
@@ -102,7 +105,7 @@ IF(BUILD_AS_BUNDLE AND (APPLE OR WIN32))
|
|||||||
IF(WIN32)
|
IF(WIN32)
|
||||||
file(TO_CMAKE_PATH "$ENV{K4A_ROOT_DIR}" ENV_K4A_ROOT_DIR)
|
file(TO_CMAKE_PATH "$ENV{K4A_ROOT_DIR}" ENV_K4A_ROOT_DIR)
|
||||||
INSTALL(FILES "${ENV_K4A_ROOT_DIR}/tools/depthengine_2_0.dll"
|
INSTALL(FILES "${ENV_K4A_ROOT_DIR}/tools/depthengine_2_0.dll"
|
||||||
DESTINATION ${plugin_dest_dir}
|
DESTINATION ${thirdparty_dest_dir}
|
||||||
COMPONENT runtime)
|
COMPONENT runtime)
|
||||||
ENDIF(WIN32)
|
ENDIF(WIN32)
|
||||||
ENDIF(k4a_FOUND)
|
ENDIF(k4a_FOUND)
|
||||||
@@ -117,7 +120,7 @@ IF(BUILD_AS_BUNDLE AND (APPLE OR WIN32))
|
|||||||
MESSAGE(STATUS "Found ${CUDNN_OPS_DLL}")
|
MESSAGE(STATUS "Found ${CUDNN_OPS_DLL}")
|
||||||
MESSAGE(STATUS "Found ${CUDNN_CNN_DLL}")
|
MESSAGE(STATUS "Found ${CUDNN_CNN_DLL}")
|
||||||
INSTALL(FILES ${CUDNN_OPS_DLL} ${CUDNN_CNN_DLL}
|
INSTALL(FILES ${CUDNN_OPS_DLL} ${CUDNN_CNN_DLL}
|
||||||
DESTINATION ${plugin_dest_dir}
|
DESTINATION ${thirdparty_dest_dir}
|
||||||
COMPONENT runtime)
|
COMPONENT runtime)
|
||||||
ELSE()
|
ELSE()
|
||||||
MESSAGE(AUTHOR_WARNING "Using Torch with CUDA, but cudnn_ops_infer64_8.dll and cudnn_cnn_infer64_8.dll are not found on the PATH, so it won't be added to package.")
|
MESSAGE(AUTHOR_WARNING "Using Torch with CUDA, but cudnn_ops_infer64_8.dll and cudnn_cnn_infer64_8.dll are not found on the PATH, so it won't be added to package.")
|
||||||
@@ -132,82 +135,94 @@ IF(BUILD_AS_BUNDLE AND (APPLE OR WIN32))
|
|||||||
file(GENERATE OUTPUT ${deploy_script} CONTENT "
|
file(GENERATE OUTPUT ${deploy_script} CONTENT "
|
||||||
# Including the file pointed to by QT_DEPLOY_SUPPORT ensures the generated
|
# Including the file pointed to by QT_DEPLOY_SUPPORT ensures the generated
|
||||||
# deployment script has access to qt_deploy_runtime_dependencies()
|
# deployment script has access to qt_deploy_runtime_dependencies()
|
||||||
include(\"${QT_DEPLOY_SUPPORT}\")
|
include(\"${QT_DEPLOY_SUPPORT}\")
|
||||||
qt_deploy_runtime_dependencies(
|
qt_deploy_runtime_dependencies(
|
||||||
EXECUTABLE \"${APPS}\"
|
EXECUTABLE \"${APPS}\"
|
||||||
|
PLUGINS_DIR ${plugin_dest_dir}
|
||||||
|
GENERATE_QT_CONF
|
||||||
|
NO_TRANSLATIONS
|
||||||
VERBOSE
|
VERBOSE
|
||||||
PLUGINS_DIR ${plugin_dest_dir}/plugins
|
|
||||||
)")
|
)")
|
||||||
|
IF("${CMAKE_BUILD_TYPE}" STREQUAL "" OR "${CMAKE_BUILD_TYPE}" STREQUAL "Debug")
|
||||||
install(SCRIPT "${CMAKE_CURRENT_BINARY_DIR}/deploy_appDebug.cmake"
|
install(SCRIPT "${CMAKE_CURRENT_BINARY_DIR}/deploy_appDebug.cmake"
|
||||||
CONFIGURATIONS Debug
|
CONFIGURATIONS Debug
|
||||||
COMPONENT runtime)
|
COMPONENT runtime)
|
||||||
install(SCRIPT "${CMAKE_CURRENT_BINARY_DIR}/deploy_appRelease.cmake"
|
ENDIF()
|
||||||
CONFIGURATIONS Release
|
IF("${CMAKE_BUILD_TYPE}" STREQUAL "" OR "${CMAKE_BUILD_TYPE}" STREQUAL "Release")
|
||||||
COMPONENT runtime)
|
install(SCRIPT "${CMAKE_CURRENT_BINARY_DIR}/deploy_appRelease.cmake"
|
||||||
install(SCRIPT "${CMAKE_CURRENT_BINARY_DIR}/deploy_appRelWithDebInfo.cmake"
|
CONFIGURATIONS Release
|
||||||
CONFIGURATIONS RelWithDebInfo
|
COMPONENT runtime)
|
||||||
COMPONENT runtime)
|
ENDIF()
|
||||||
install(SCRIPT "${CMAKE_CURRENT_BINARY_DIR}/deploy_appMinSizeRel.cmake"
|
IF("${CMAKE_BUILD_TYPE}" STREQUAL "" OR "${CMAKE_BUILD_TYPE}" STREQUAL "RelWithDebInfo")
|
||||||
CONFIGURATIONS MinSizeRel
|
install(SCRIPT "${CMAKE_CURRENT_BINARY_DIR}/deploy_appRelWithDebInfo.cmake"
|
||||||
COMPONENT runtime)
|
CONFIGURATIONS RelWithDebInfo
|
||||||
|
COMPONENT runtime)
|
||||||
|
ENDIF()
|
||||||
|
IF("${CMAKE_BUILD_TYPE}" STREQUAL "" OR "${CMAKE_BUILD_TYPE}" STREQUAL "MinSizeRel")
|
||||||
|
install(SCRIPT "${CMAKE_CURRENT_BINARY_DIR}/deploy_appMinSizeRel.cmake"
|
||||||
|
CONFIGURATIONS MinSizeRel
|
||||||
|
COMPONENT runtime)
|
||||||
|
ENDIF()
|
||||||
ELSEIF(Qt5_FOUND)
|
ELSEIF(Qt5_FOUND)
|
||||||
#Qt5
|
#Qt5
|
||||||
foreach(plugin ${Qt5Gui_PLUGINS})
|
foreach(plugin ${Qt5Gui_PLUGINS})
|
||||||
get_target_property(plugin_loc ${plugin} LOCATION)
|
get_target_property(plugin_loc ${plugin} LOCATION)
|
||||||
get_filename_component(plugin_dir ${plugin_loc} DIRECTORY)
|
get_filename_component(plugin_dir ${plugin_loc} DIRECTORY)
|
||||||
string(REPLACE "plugins" ";" loc_list ${plugin_dir})
|
string(REPLACE "plugins" ";" loc_list ${plugin_dir})
|
||||||
list(GET loc_list 1 plugin_type)
|
list(GET loc_list 1 plugin_type)
|
||||||
IF(NOT plugin_root)
|
IF(NOT plugin_root)
|
||||||
get_filename_component(plugin_root ${plugin_dir} DIRECTORY)
|
get_filename_component(plugin_root ${plugin_dir} DIRECTORY)
|
||||||
ENDIF(NOT plugin_root)
|
ENDIF(NOT plugin_root)
|
||||||
#MESSAGE(STATUS "Qt5 plugin \"${plugin_loc}\" installed in \"${plugin_dest_dir}/plugins${plugin_type}\"")
|
#MESSAGE(STATUS "Qt5 plugin \"${plugin_loc}\" installed in \"${plugin_dest_dir}${plugin_type}\"")
|
||||||
INSTALL(FILES ${plugin_loc}
|
INSTALL(FILES ${plugin_loc}
|
||||||
DESTINATION ${plugin_dest_dir}/plugins${plugin_type}
|
DESTINATION ${plugin_dest_dir}${plugin_type}
|
||||||
COMPONENT runtime)
|
COMPONENT runtime)
|
||||||
endforeach()
|
endforeach()
|
||||||
IF(NOT Qt5Widgets_VERSION VERSION_LESS 5.10.0)
|
IF(NOT Qt5Widgets_VERSION VERSION_LESS 5.10.0)
|
||||||
IF(WIN32)
|
IF(WIN32)
|
||||||
SET(plugin_loc "${plugin_root}/styles/qwindowsvistastyle.dll")
|
SET(plugin_loc "${plugin_root}/styles/qwindowsvistastyle.dll")
|
||||||
ELSEIF(APPLE)
|
ELSEIF(APPLE)
|
||||||
SET(plugin_loc "${plugin_root}/styles/libqmacstyle.dylib")
|
SET(plugin_loc "${plugin_root}/styles/libqmacstyle.dylib")
|
||||||
ENDIF()
|
ENDIF()
|
||||||
IF(EXISTS ${plugin_loc})
|
IF(EXISTS ${plugin_loc})
|
||||||
get_filename_component(plugin_dir ${plugin_loc} DIRECTORY)
|
get_filename_component(plugin_dir ${plugin_loc} DIRECTORY)
|
||||||
string(REPLACE "plugins" ";" loc_list ${plugin_dir})
|
string(REPLACE "plugins" ";" loc_list ${plugin_dir})
|
||||||
list(GET loc_list 1 plugin_type)
|
list(GET loc_list 1 plugin_type)
|
||||||
INSTALL(FILES ${plugin_loc}
|
INSTALL(FILES ${plugin_loc}
|
||||||
DESTINATION ${plugin_dest_dir}/plugins${plugin_type}
|
DESTINATION ${plugin_dest_dir}/plugins${plugin_type}
|
||||||
COMPONENT runtime)
|
COMPONENT runtime)
|
||||||
#MESSAGE(STATUS "Qt5 plugin \"${plugin_loc}\" installed in \"${plugin_dest_dir}/plugins${plugin_type}\"")
|
#MESSAGE(STATUS "Qt5 plugin \"${plugin_loc}\" installed in \"${plugin_dest_dir}${plugin_type}\"")
|
||||||
ENDIF(EXISTS ${plugin_loc})
|
ENDIF(EXISTS ${plugin_loc})
|
||||||
ENDIF(NOT Qt5Widgets_VERSION VERSION_LESS 5.10.0)
|
ENDIF(NOT Qt5Widgets_VERSION VERSION_LESS 5.10.0)
|
||||||
ELSEIF(QT_PLUGINS_DIR) # Qt4
|
ELSEIF(QT_PLUGINS_DIR) # Qt4
|
||||||
# Install needed Qt plugins by copying directories from the qt installation
|
# Install needed Qt plugins by copying directories from the qt installation
|
||||||
# One can cull what gets copied by using 'REGEX "..." EXCLUDE'
|
# One can cull what gets copied by using 'REGEX "..." EXCLUDE'
|
||||||
# Exclude debug libraries
|
# Exclude debug libraries
|
||||||
INSTALL(DIRECTORY "${QT_PLUGINS_DIR}/imageformats"
|
INSTALL(DIRECTORY "${QT_PLUGINS_DIR}/imageformats"
|
||||||
DESTINATION ${plugin_dest_dir}/plugins
|
DESTINATION ${plugin_dest_dir}
|
||||||
COMPONENT runtime
|
COMPONENT runtime
|
||||||
REGEX ".*d4.dll" EXCLUDE
|
REGEX ".*d4.dll" EXCLUDE
|
||||||
REGEX ".*d4.a" EXCLUDE)
|
REGEX ".*d4.a" EXCLUDE)
|
||||||
ENDIF()
|
ENDIF()
|
||||||
|
|
||||||
# install a qt.conf file
|
IF(Qt5_FOUND OR QT4_FOUND)
|
||||||
# this inserts some cmake code into the install script to write the file
|
# install a qt.conf file
|
||||||
SET(QT_CONF_FILE [Paths]\nPlugins=plugins)
|
# this inserts some cmake code into the install script to write the file
|
||||||
IF(APPLE)
|
SET(QT_CONF_FILE [Paths]\nPlugins=plugins)
|
||||||
SET(QT_CONF_FILE [Paths]\nPlugins=MacOS/plugins)
|
IF(APPLE)
|
||||||
ENDIF(APPLE)
|
SET(QT_CONF_FILE [Paths]\nPlugins=MacOS/plugins)
|
||||||
INSTALL(CODE "
|
ENDIF(APPLE)
|
||||||
file(WRITE \"\$ENV{DESTDIR}\${CMAKE_INSTALL_PREFIX}/${qtconf_dest_dir}/qt.conf\" \"${QT_CONF_FILE}\")
|
INSTALL(CODE "
|
||||||
" COMPONENT runtime)
|
file(WRITE \"\$ENV{DESTDIR}\${CMAKE_INSTALL_PREFIX}/${qtconf_dest_dir}/qt.conf\" \"${QT_CONF_FILE}\")
|
||||||
|
" COMPONENT runtime)
|
||||||
|
ENDIF()
|
||||||
|
|
||||||
# directories to look for dependencies
|
# directories to look for dependencies
|
||||||
SET(DIRS ${QT_LIBRARY_DIRS} ${PROJECT_BINARY_DIR}/bin)
|
SET(DIRS "${QT_LIBRARY_DIRS}" "\$ENV{DESTDIR}\${CMAKE_INSTALL_PREFIX}/lib")
|
||||||
IF(APPLE)
|
IF(APPLE)
|
||||||
SET(DIRS ${DIRS} /usr/local /usr/local/lib /opt/homebrew /opt/homebrew/lib /opt/homebrew/lib/gcc/current)
|
SET(DIRS ${DIRS} /usr/local /usr/local/lib /opt/homebrew /opt/homebrew/lib /opt/homebrew/lib/gcc/current)
|
||||||
ENDIF(APPLE)
|
ENDIF(APPLE)
|
||||||
|
|
||||||
# Now the work of copying dependencies into the bundle/package
|
# Now the work of copying dependencies into the bundle/package
|
||||||
# The quotes are escaped and variables to use at install time have their $ escaped
|
# The quotes are escaped and variables to use at install time have their $ escaped
|
||||||
# An alternative is the do a configure_file() on a script and use install(SCRIPT ...).
|
# An alternative is the do a configure_file() on a script and use install(SCRIPT ...).
|
||||||
@@ -215,10 +230,11 @@ IF(BUILD_AS_BUNDLE AND (APPLE OR WIN32))
|
|||||||
# over.
|
# over.
|
||||||
# To find dependencies, cmake use "otool" on Apple and "dumpbin" on Windows (make sure you have one of them).
|
# To find dependencies, cmake use "otool" on Apple and "dumpbin" on Windows (make sure you have one of them).
|
||||||
install(CODE "
|
install(CODE "
|
||||||
file(GLOB_RECURSE QTPLUGINS \"\$ENV{DESTDIR}\${CMAKE_INSTALL_PREFIX}/${plugin_dest_dir}/plugins/*${CMAKE_SHARED_LIBRARY_SUFFIX}\")
|
file(GLOB_RECURSE QTPLUGINS \"\$ENV{DESTDIR}\${CMAKE_INSTALL_PREFIX}/${plugin_dest_dir}/*${CMAKE_SHARED_LIBRARY_SUFFIX}\")
|
||||||
set(BU_CHMOD_BUNDLE_ITEMS ON)
|
set(BU_CHMOD_BUNDLE_ITEMS ON)
|
||||||
include(\"BundleUtilities\")
|
include(\"BundleUtilities\")
|
||||||
fixup_bundle(\"${APPS}\" \"\${QTPLUGINS}\" \"${DIRS}\")
|
fixup_bundle(\"${APPS}\" \"\${QTPLUGINS}\" \"${DIRS}\")
|
||||||
" COMPONENT runtime)
|
" COMPONENT runtime)
|
||||||
|
|
||||||
ENDIF(BUILD_AS_BUNDLE AND (APPLE OR WIN32))
|
ENDIF(BUILD_AS_BUNDLE AND (APPLE OR WIN32))
|
||||||
|
|
||||||
|
|||||||
@@ -55,9 +55,6 @@ int main(int argc, char* argv[])
|
|||||||
CoInitialize(nullptr);
|
CoInitialize(nullptr);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if VTK_MAJOR_VERSION >= 8 && defined(BUILD_AS_BUNDLE)
|
|
||||||
vtkObject::GlobalWarningDisplayOff();
|
|
||||||
#endif
|
|
||||||
#if VTK_MAJOR_VERSION > 9 || (VTK_MAJOR_VERSION==9 && VTK_MINOR_VERSION >= 1)
|
#if VTK_MAJOR_VERSION > 9 || (VTK_MAJOR_VERSION==9 && VTK_MINOR_VERSION >= 1)
|
||||||
// needed to ensure appropriate OpenGL context is created for VTK rendering.
|
// needed to ensure appropriate OpenGL context is created for VTK rendering.
|
||||||
QSurfaceFormat::setDefaultFormat(QVTKRenderWidget::defaultFormat());
|
QSurfaceFormat::setDefaultFormat(QVTKRenderWidget::defaultFormat());
|
||||||
|
|||||||
25
archive/2010-LoopClosure/README.md
Normal file
25
archive/2010-LoopClosure/README.md
Normal file
@@ -0,0 +1,25 @@
|
|||||||
|
|
||||||
|
To reproduce results (based on parameters of this [paper](https://introlab.3it.usherbrooke.ca/mediawiki-introlab/images/b/bc/TRO2013.pdf)):
|
||||||
|
|
||||||
|
```
|
||||||
|
rtabmap-console \
|
||||||
|
--Rtabmap/StatisticLogged true\
|
||||||
|
--Rtabmap/StatisticLoggedHeaders false\
|
||||||
|
--Kp/DetectorStrategy 0\
|
||||||
|
--Rtabmap/MemoryThr 300\
|
||||||
|
--Rtabmap/LoopRatio 0.9\
|
||||||
|
--SURF/HessianThreshold 150\
|
||||||
|
--Mem/STMSize 30\
|
||||||
|
--Vis/MaxFeatures 400\
|
||||||
|
--Kp/TfIdfLikelihoodUsed false\
|
||||||
|
--Kp/MaxFeatures 400\
|
||||||
|
--Kp/BadSignRatio 0.25\
|
||||||
|
--Mem/BadSignaturesIgnored true\
|
||||||
|
--Mem/RehearsalSimilarity 0.20\
|
||||||
|
--Mem/RecentWmRatio 0.2\
|
||||||
|
-gt "~/Downloads/UdeS_1Hz.png"\
|
||||||
|
~/Downloads/UdeS_1Hz
|
||||||
|
```
|
||||||
|
Adding the ground truth file here is optional to show recall at 100% precision at the end of the process directly without using the octave/MATLAB script below. For NewCollege and CityCentre datasets, `rtabmap-imagesJoiner` can be used to assemble the left and right images together.
|
||||||
|
|
||||||
|
To analyze with Octave/MATLAB, drop `LogF.txt` and `LogI.txt` generated files from command above in ShowLogs directly, then execute `showLogs.m`.
|
||||||
@@ -1,4 +0,0 @@
|
|||||||
This directory contains some basic concepts on Bayes filtering.
|
|
||||||
Main scripts :
|
|
||||||
RecursivesBayes.m
|
|
||||||
RecursivesBayesAvpd.m
|
|
||||||
@@ -32,8 +32,7 @@ if ~isempty(GroundTruth)
|
|||||||
if size(GroundTruth, 1) ~= length(LogF(:,1)) || size(GroundTruth, 1) ~= length(LogI(:,1))
|
if size(GroundTruth, 1) ~= length(LogF(:,1)) || size(GroundTruth, 1) ~= length(LogI(:,1))
|
||||||
error(['The ground truth size doesn''t match the log files (LogI=' num2str(length(LogI(:,1))) ', LogF=' num2str(length(LogF(:,1))) ', GT=' num2str(size(GroundTruth, 1)) ')'])
|
error(['The ground truth size doesn''t match the log files (LogI=' num2str(length(LogI(:,1))) ', LogF=' num2str(length(LogF(:,1))) ', GT=' num2str(size(GroundTruth, 1)) ')'])
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
%[highestHypot, CorrespondingID, GT, Accepted, Good, Index, UnderLoopRatio] descending order
|
%[highestHypot, CorrespondingID, GT, Accepted, Good, Index, UnderLoopRatio] descending order
|
||||||
if(sum(LogI(:,8) == 10) > 0)
|
if(sum(LogI(:,8) == 10) > 0)
|
||||||
%OLD
|
%OLD
|
||||||
@@ -111,14 +110,14 @@ if ~isempty(GroundTruth)
|
|||||||
index = find(PR(:,1) == 1);
|
index = find(PR(:,1) == 1);
|
||||||
if ~isempty(index)
|
if ~isempty(index)
|
||||||
maxRecall = PR(index(end),2) * 100;
|
maxRecall = PR(index(end),2) * 100;
|
||||||
display(['Recall max (Precision=100%) = ' num2str(maxRecall) '% (p=' num2str(lc(index(end),1)) '), accepted=' num2str(sum(lc(1:index(end),5) & ~lc(1:index(end),7) & lc(1:index(end),2)))])
|
display(['Recall max (Precision=100%) = ' num2str(maxRecall) '% (p=' num2str(lc(index(end),1)) '), accepted=' num2str(sum(lc(1:index(end),5) & ~lc(1:index(end),7) & lc(1:index(end),2))) '/' num2str(GT_total_positives)])
|
||||||
else
|
else
|
||||||
display('Recall max (Precision=100%) = 0')
|
display('Recall max (Precision=100%) = 0')
|
||||||
end
|
end
|
||||||
indexAccepted = find(PR(:,3) == 1);
|
indexAccepted = find(PR(:,3) == 1);
|
||||||
if ~isempty(indexAccepted)
|
if ~isempty(indexAccepted)
|
||||||
maxRecall = PR(indexAccepted(end),2) * 100;
|
maxRecall = PR(indexAccepted(end),2) * 100;
|
||||||
display(['Recall max accepted (Precision=100%) = ' num2str(maxRecall) '% (p=' num2str(lc(indexAccepted(end),1)) '), accepted=' num2str(sum(lc(1:indexAccepted(end),5) & ~lc(1:indexAccepted(end),7) & lc(1:indexAccepted(end),2)))])
|
display(['Recall max accepted (Precision=100%) = ' num2str(maxRecall) '% (p=' num2str(lc(indexAccepted(end),1)) '), accepted=' num2str(sum(lc(1:indexAccepted(end),5) & ~lc(1:indexAccepted(end),7) & lc(1:indexAccepted(end),2))) '/' num2str(GT_total_positives)])
|
||||||
else
|
else
|
||||||
display('Recall max accepted (Precision=100%) = 0')
|
display('Recall max accepted (Precision=100%) = 0')
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -22,6 +22,8 @@ function [LogF LogI] = showlogs(PathPrefix, GT_file)
|
|||||||
set(0,'defaultAxesFontName', 'Times')
|
set(0,'defaultAxesFontName', 'Times')
|
||||||
set(0,'defaultTextFontName', 'Times')
|
set(0,'defaultTextFontName', 'Times')
|
||||||
|
|
||||||
|
close all
|
||||||
|
|
||||||
if nargin < 2, GT_file = ''; end
|
if nargin < 2, GT_file = ''; end
|
||||||
if nargin < 1, PathPrefix = '.'; end
|
if nargin < 1, PathPrefix = '.'; end
|
||||||
|
|
||||||
@@ -325,7 +327,7 @@ y(LogI(:, 1) == 0) = [];
|
|||||||
x(LogI(:, 1) == 0) = [];
|
x(LogI(:, 1) == 0) = [];
|
||||||
plot(x,y, 'g.')
|
plot(x,y, 'g.')
|
||||||
|
|
||||||
set(datacursormode,'UpdateFcn',@(Y,X){sprintf('X: %0.2f',X.Position(1)),sprintf('Y: %0.2f',X.Position(2))})
|
%set(datacursormode,'UpdateFcn',@(Y,X){sprintf('X: %0.2f',X.Position(1)),sprintf('Y: %0.2f',X.Position(2))})
|
||||||
% %matched sign words
|
% %matched sign words
|
||||||
% y = LogI(:,2);
|
% y = LogI(:,2);
|
||||||
% x = 1:length(y);
|
% x = 1:length(y);
|
||||||
|
|||||||
8
archive/2010-LoopClosure/run_all.sh
Executable file
8
archive/2010-LoopClosure/run_all.sh
Executable file
@@ -0,0 +1,8 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
SCRIPT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" &> /dev/null && pwd )"
|
||||||
|
|
||||||
|
$SCRIPT_DIR/run_bow.sh ~/loop_closure_detection_datasets/NewCollege ~/loop_closure_detection_datasets/NewCollege.png
|
||||||
|
$SCRIPT_DIR/run_bow.sh ~/loop_closure_detection_datasets/CityCentre ~/loop_closure_detection_datasets/CityCentre.png
|
||||||
|
$SCRIPT_DIR/run_bow.sh ~/loop_closure_detection_datasets/UdeS_1Hz ~/loop_closure_detection_datasets/UdeS_1Hz.png
|
||||||
|
|
||||||
32
archive/2010-LoopClosure/run_bow.sh
Executable file
32
archive/2010-LoopClosure/run_bow.sh
Executable file
@@ -0,0 +1,32 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
DATASET_FOLDER=""
|
||||||
|
GT_FILE=""
|
||||||
|
if [ $# -eq 2 ]
|
||||||
|
then
|
||||||
|
DATASET_FOLDER=$1
|
||||||
|
GT_FILE=$2
|
||||||
|
else
|
||||||
|
echo "Usage: run_bow.sh \"dataset folder\" \"ground truth file\""
|
||||||
|
exit
|
||||||
|
fi
|
||||||
|
|
||||||
|
rtabmap-console \
|
||||||
|
-quiet \
|
||||||
|
--Rtabmap/StatisticLogged true\
|
||||||
|
--Rtabmap/StatisticLoggedHeaders false\
|
||||||
|
--Kp/DetectorStrategy 0\
|
||||||
|
--SURF/HessianThreshold 150\
|
||||||
|
--Rtabmap/MemoryThr 300\
|
||||||
|
--Rtabmap/LoopRatio 0.9\
|
||||||
|
--Mem/STMSize 30\
|
||||||
|
--Vis/MaxFeatures 400\
|
||||||
|
--Kp/TfIdfLikelihoodUsed false\
|
||||||
|
--Kp/MaxFeatures 400\
|
||||||
|
--Kp/BadSignRatio 0.25\
|
||||||
|
--Mem/BadSignaturesIgnored true\
|
||||||
|
--Mem/RehearsalSimilarity 0.20\
|
||||||
|
--Mem/RecentWmRatio 0.20\
|
||||||
|
-gt "$GT_FILE"\
|
||||||
|
"$DATASET_FOLDER"
|
||||||
|
|
||||||
@@ -25,14 +25,14 @@ The following image shows when we do the same localization experiment at differe
|
|||||||
|
|
||||||
We provide two formats: the first one is more general and the second one is used to produce the results in this paper with RTAB-Map. Please open issue if the links are outdated.
|
We provide two formats: the first one is more general and the second one is used to produce the results in this paper with RTAB-Map. Please open issue if the links are outdated.
|
||||||
|
|
||||||
* [Images](https://usherbrooke-my.sharepoint.com/:u:/g/personal/labm2414_usherbrooke_ca/EV8F4PZUxOxLhwAyEehlzKwBjF-9xNuxR32Q4mUjx5u-rA?e=eCJ3TW):
|
* [Images](https://drive.google.com/file/d/1fUm1m8oW6q8qlThx7BjrBH2vrVbNQ9bQ/view?usp=drive_link):
|
||||||
* `rgb`: folder containing *.jpg color camera images
|
* `rgb`: folder containing *.jpg color camera images
|
||||||
* `depth`: folder containing *.png 16bits mm depth images
|
* `depth`: folder containing *.png 16bits mm depth images
|
||||||
* `calib`: folder containing calibration for each color image. Each calibration contains also the transform between `device` and `camera` frames as `local_transform`.
|
* `calib`: folder containing calibration for each color image. Each calibration contains also the transform between `device` and `camera` frames as `local_transform`.
|
||||||
* `device_poses.txt`: VIO poses of each image in `device` frame
|
* `device_poses.txt`: VIO poses of each image in `device` frame
|
||||||
* `camera_poses.txt`: VIO poses of each image in `camera` frame
|
* `camera_poses.txt`: VIO poses of each image in `camera` frame
|
||||||
* [RTAB-Map Databases](https://usherbrooke-my.sharepoint.com/:u:/g/personal/labm2414_usherbrooke_ca/EU5fb0jEKzlGhPK3OWjMGLUBnDo1BRAoZwtB2czyeVLE_A?e=Y0JyXY)
|
* [RTAB-Map Databases](https://drive.google.com/file/d/1TklUcTKFSrcg8b0t0U80G_IpFRMVRlY5/view?usp=drive_link)
|
||||||
|
* Dataset now also available on [Federated Research Data Repository (FRDR)](https://doi.org/10.20383/103.0931) (if links above don't work)
|
||||||
|
|
||||||
|
|
||||||
## How reproduce results shown in the paper
|
## How reproduce results shown in the paper
|
||||||
|
|||||||
@@ -1,30 +0,0 @@
|
|||||||
# - Find Sqlite3
|
|
||||||
# This module finds an installed Sqlite3 package.
|
|
||||||
#
|
|
||||||
# It sets the following variables:
|
|
||||||
# Sqlite3_FOUND - Set to false, or undefined, if Sqlite3 isn't found.
|
|
||||||
# Sqlite3_INCLUDE_DIR - The Sqlite3 include directory.
|
|
||||||
# Sqlite3_LIBRARY - The Sqlite3 library to link against.
|
|
||||||
|
|
||||||
FIND_PATH(Sqlite3_INCLUDE_DIR sqlite3.h PATHS $ENV{Sqlite3_ROOT_DIR}/include $ENV{Sqlite3_ROOT_DIR})
|
|
||||||
|
|
||||||
FIND_LIBRARY(Sqlite3_LIBRARY NAMES sqlite3 PATHS $ENV{Sqlite3_ROOT_DIR}/lib $ENV{Sqlite3_ROOT_DIR})
|
|
||||||
|
|
||||||
IF (Sqlite3_INCLUDE_DIR AND Sqlite3_LIBRARY)
|
|
||||||
SET(Sqlite3_FOUND TRUE)
|
|
||||||
SET(Sqlite3_INCLUDE_DIRS ${Sqlite3_INCLUDE_DIR})
|
|
||||||
SET(Sqlite3_LIBRARIES ${Sqlite3_LIBRARY})
|
|
||||||
ENDIF (Sqlite3_INCLUDE_DIR AND Sqlite3_LIBRARY)
|
|
||||||
|
|
||||||
IF (Sqlite3_FOUND)
|
|
||||||
# show which Sqlite3 was found only if not quiet
|
|
||||||
IF (NOT Sqlite3_FIND_QUIETLY)
|
|
||||||
MESSAGE(STATUS "Found Sqlite3: ${Sqlite3_INCLUDE_DIRS} ${Sqlite3_LIBRARIES}")
|
|
||||||
ENDIF (NOT Sqlite3_FIND_QUIETLY)
|
|
||||||
ELSE (Sqlite3_FOUND)
|
|
||||||
# fatal error if Sqlite3 is required but not found
|
|
||||||
IF (Sqlite3_FIND_REQUIRED)
|
|
||||||
MESSAGE(FATAL_ERROR "Could not find Sqlite3")
|
|
||||||
ENDIF (Sqlite3_FIND_REQUIRED)
|
|
||||||
ENDIF (Sqlite3_FOUND)
|
|
||||||
|
|
||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
Copyright (c) 2010-2016, Mathieu Labbe - IntRoLab - Universite de Sherbrooke
|
Copyright (c) 2010-2022, Mathieu Labbe - IntRoLab - Universite de Sherbrooke
|
||||||
All rights reserved.
|
All rights reserved.
|
||||||
|
|
||||||
Redistribution and use in source and binary forms, with or without
|
Redistribution and use in source and binary forms, with or without
|
||||||
@@ -28,47 +28,32 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include "rtabmap/core/rtabmap_core_export.h" // DLL export/import defines
|
#include "rtabmap/core/rtabmap_core_export.h" // DLL export/import defines
|
||||||
|
#include <rtabmap/core/SensorCapture.h>
|
||||||
#include <opencv2/highgui/highgui.hpp>
|
#include <rtabmap/core/IMU.h>
|
||||||
#include "rtabmap/core/SensorData.h"
|
|
||||||
#include "rtabmap/core/CameraInfo.h"
|
|
||||||
#include <set>
|
|
||||||
#include <stack>
|
|
||||||
#include <list>
|
|
||||||
#include <vector>
|
|
||||||
|
|
||||||
class UDirectory;
|
|
||||||
class UTimer;
|
|
||||||
|
|
||||||
namespace rtabmap
|
namespace rtabmap
|
||||||
{
|
{
|
||||||
|
|
||||||
|
class IMUFilter;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Class Camera
|
* Class Camera
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
class RTABMAP_CORE_EXPORT Camera
|
class RTABMAP_CORE_EXPORT Camera : public SensorCapture
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
virtual ~Camera();
|
virtual ~Camera();
|
||||||
SensorData takeImage(CameraInfo * info = 0);
|
|
||||||
|
SensorData takeImage(SensorCaptureInfo * info = 0) {return takeData(info);}
|
||||||
|
float getImageRate() const {return getFrameRate();}
|
||||||
|
void setImageRate(float imageRate) {setFrameRate(imageRate);}
|
||||||
|
void setInterIMUPublishing(bool enabled, IMUFilter * filter = 0); // Take ownership of filter
|
||||||
|
bool isInterIMUPublishing() const {return publishInterIMU_;}
|
||||||
|
|
||||||
bool initFromFile(const std::string & calibrationPath);
|
bool initFromFile(const std::string & calibrationPath);
|
||||||
virtual bool init(const std::string & calibrationFolder = ".", const std::string & cameraName = "") = 0;
|
|
||||||
virtual bool isCalibrated() const = 0;
|
virtual bool isCalibrated() const = 0;
|
||||||
virtual std::string getSerial() const = 0;
|
|
||||||
virtual bool odomProvided() const { return false; }
|
|
||||||
virtual bool getPose(double stamp, Transform & pose, cv::Mat & covariance) { return false; }
|
|
||||||
|
|
||||||
//getters
|
|
||||||
float getImageRate() const {return _imageRate;}
|
|
||||||
const Transform & getLocalTransform() const {return _localTransform;}
|
|
||||||
|
|
||||||
//setters
|
|
||||||
void setImageRate(float imageRate) {_imageRate = imageRate;}
|
|
||||||
void setLocalTransform(const Transform & localTransform) {_localTransform= localTransform;}
|
|
||||||
|
|
||||||
void resetTimer();
|
|
||||||
protected:
|
protected:
|
||||||
/**
|
/**
|
||||||
* Constructor
|
* Constructor
|
||||||
@@ -78,19 +63,16 @@ protected:
|
|||||||
*/
|
*/
|
||||||
Camera(float imageRate = 0, const Transform & localTransform = Transform::getIdentity());
|
Camera(float imageRate = 0, const Transform & localTransform = Transform::getIdentity());
|
||||||
|
|
||||||
/**
|
virtual SensorData captureImage(SensorCaptureInfo * info = 0) = 0;
|
||||||
* returned rgb and depth images should be already rectified if calibration was loaded
|
|
||||||
*/
|
|
||||||
virtual SensorData captureImage(CameraInfo * info = 0) = 0;
|
|
||||||
|
|
||||||
int getNextSeqID() {return ++_seq;}
|
void postInterIMU(const IMU & imu, double stamp);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
float _imageRate;
|
virtual SensorData captureData(SensorCaptureInfo * info = 0) {return captureImage(info);}
|
||||||
Transform _localTransform;
|
|
||||||
cv::Size _targetImageSize;
|
private:
|
||||||
UTimer * _frameRateTimer;
|
IMUFilter * imuFilter_;
|
||||||
int _seq;
|
bool publishInterIMU_;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -27,65 +27,4 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <rtabmap/utilite/UEvent.h>
|
#include "rtabmap/core/SensorEvent.h"
|
||||||
#include "rtabmap/core/SensorData.h"
|
|
||||||
#include "rtabmap/core/CameraInfo.h"
|
|
||||||
|
|
||||||
namespace rtabmap
|
|
||||||
{
|
|
||||||
|
|
||||||
class CameraEvent :
|
|
||||||
public UEvent
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
enum Code {
|
|
||||||
kCodeData,
|
|
||||||
kCodeNoMoreImages
|
|
||||||
};
|
|
||||||
|
|
||||||
public:
|
|
||||||
CameraEvent(const cv::Mat & image, int seq=0, double stamp = 0.0, const std::string & cameraName = std::string()) :
|
|
||||||
UEvent(kCodeData),
|
|
||||||
data_(image, seq, stamp)
|
|
||||||
{
|
|
||||||
cameraInfo_.cameraName = cameraName;
|
|
||||||
}
|
|
||||||
|
|
||||||
CameraEvent() :
|
|
||||||
UEvent(kCodeNoMoreImages)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
CameraEvent(const SensorData & data) :
|
|
||||||
UEvent(kCodeData),
|
|
||||||
data_(data)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
CameraEvent(const SensorData & data, const std::string & cameraName) :
|
|
||||||
UEvent(kCodeData),
|
|
||||||
data_(data)
|
|
||||||
{
|
|
||||||
cameraInfo_.cameraName = cameraName;
|
|
||||||
}
|
|
||||||
CameraEvent(const SensorData & data, const CameraInfo & cameraInfo) :
|
|
||||||
UEvent(kCodeData),
|
|
||||||
data_(data),
|
|
||||||
cameraInfo_(cameraInfo)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
// Image or descriptors
|
|
||||||
const SensorData & data() const {return data_;}
|
|
||||||
const std::string & cameraName() const {return cameraInfo_.cameraName;}
|
|
||||||
const CameraInfo & info() const {return cameraInfo_;}
|
|
||||||
|
|
||||||
virtual ~CameraEvent() {}
|
|
||||||
virtual std::string getClassName() const {return std::string("CameraEvent");}
|
|
||||||
|
|
||||||
private:
|
|
||||||
SensorData data_;
|
|
||||||
CameraInfo cameraInfo_;
|
|
||||||
};
|
|
||||||
|
|
||||||
} // namespace rtabmap
|
|
||||||
|
|||||||
@@ -27,50 +27,4 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <string>
|
#include "rtabmap/core/SensorCaptureInfo.h"
|
||||||
|
|
||||||
namespace rtabmap
|
|
||||||
{
|
|
||||||
|
|
||||||
class CameraInfo
|
|
||||||
{
|
|
||||||
|
|
||||||
public:
|
|
||||||
CameraInfo() :
|
|
||||||
cameraName(""),
|
|
||||||
id(0),
|
|
||||||
stamp(0.0),
|
|
||||||
timeCapture(0.0f),
|
|
||||||
timeDisparity(0.0f),
|
|
||||||
timeMirroring(0.0f),
|
|
||||||
timeStereoExposureCompensation(0.0f),
|
|
||||||
timeImageDecimation(0.0f),
|
|
||||||
timeHistogramEqualization(0.0f),
|
|
||||||
timeScanFromDepth(0.0f),
|
|
||||||
timeUndistortDepth(0.0f),
|
|
||||||
timeBilateralFiltering(0.0f),
|
|
||||||
timeTotal(0.0f),
|
|
||||||
odomCovariance(cv::Mat::eye(6,6,CV_64FC1))
|
|
||||||
{
|
|
||||||
}
|
|
||||||
virtual ~CameraInfo() {}
|
|
||||||
|
|
||||||
std::string cameraName;
|
|
||||||
int id;
|
|
||||||
double stamp;
|
|
||||||
float timeCapture;
|
|
||||||
float timeDisparity;
|
|
||||||
float timeMirroring;
|
|
||||||
float timeStereoExposureCompensation;
|
|
||||||
float timeImageDecimation;
|
|
||||||
float timeHistogramEqualization;
|
|
||||||
float timeScanFromDepth;
|
|
||||||
float timeUndistortDepth;
|
|
||||||
float timeBilateralFiltering;
|
|
||||||
float timeTotal;
|
|
||||||
Transform odomPose;
|
|
||||||
cv::Mat odomCovariance;
|
|
||||||
std::vector<float> odomVelocity;
|
|
||||||
};
|
|
||||||
|
|
||||||
} // namespace rtabmap
|
|
||||||
|
|||||||
@@ -37,4 +37,4 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|||||||
#include <rtabmap/core/camera/CameraRealSense2.h>
|
#include <rtabmap/core/camera/CameraRealSense2.h>
|
||||||
#include <rtabmap/core/camera/CameraRGBDImages.h>
|
#include <rtabmap/core/camera/CameraRGBDImages.h>
|
||||||
#include <rtabmap/core/camera/CameraK4A.h>
|
#include <rtabmap/core/camera/CameraK4A.h>
|
||||||
|
#include <rtabmap/core/camera/CameraSeerSense.h>
|
||||||
|
|||||||
@@ -27,136 +27,4 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include "rtabmap/core/rtabmap_core_export.h" // DLL export/import defines
|
#include "rtabmap/core/SensorCaptureThread.h"
|
||||||
|
|
||||||
#include <rtabmap/core/Parameters.h>
|
|
||||||
#include <rtabmap/core/Transform.h>
|
|
||||||
#include <rtabmap/utilite/UThread.h>
|
|
||||||
#include <rtabmap/utilite/UEventsSender.h>
|
|
||||||
|
|
||||||
namespace clams
|
|
||||||
{
|
|
||||||
class DiscreteDepthDistortionModel;
|
|
||||||
}
|
|
||||||
|
|
||||||
namespace rtabmap
|
|
||||||
{
|
|
||||||
|
|
||||||
class Camera;
|
|
||||||
class CameraInfo;
|
|
||||||
class SensorData;
|
|
||||||
class StereoDense;
|
|
||||||
class IMUFilter;
|
|
||||||
class Feature2D;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Class CameraThread
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
class RTABMAP_CORE_EXPORT CameraThread :
|
|
||||||
public UThread,
|
|
||||||
public UEventsSender
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
// ownership transferred
|
|
||||||
CameraThread(Camera * camera, const ParametersMap & parameters = ParametersMap());
|
|
||||||
/**
|
|
||||||
* @param camera the camera to take images from
|
|
||||||
* @param odomSensor an odometry sensor to get a pose
|
|
||||||
* @param extrinsics the static transform between odometry sensor's left lens frame to camera's left lens frame
|
|
||||||
*/
|
|
||||||
CameraThread(Camera * camera,
|
|
||||||
Camera * odomSensor,
|
|
||||||
const Transform & extrinsics,
|
|
||||||
double poseTimeOffset = 0.0,
|
|
||||||
float poseScaleFactor = 1.0f,
|
|
||||||
bool odomAsGt = false,
|
|
||||||
const ParametersMap & parameters = ParametersMap());
|
|
||||||
CameraThread(Camera * camera,
|
|
||||||
bool odomAsGt,
|
|
||||||
const ParametersMap & parameters = ParametersMap());
|
|
||||||
virtual ~CameraThread();
|
|
||||||
|
|
||||||
void setMirroringEnabled(bool enabled) {_mirroring = enabled;}
|
|
||||||
void setStereoExposureCompensation(bool enabled) {_stereoExposureCompensation = enabled;}
|
|
||||||
void setColorOnly(bool colorOnly) {_colorOnly = colorOnly;}
|
|
||||||
void setImageDecimation(int decimation) {_imageDecimation = decimation;}
|
|
||||||
void setHistogramMethod(int histogramMethod) {_histogramMethod = histogramMethod;}
|
|
||||||
void setStereoToDepth(bool enabled) {_stereoToDepth = enabled;}
|
|
||||||
void setImageRate(float imageRate);
|
|
||||||
void setDistortionModel(const std::string & path);
|
|
||||||
void enableBilateralFiltering(float sigmaS, float sigmaR);
|
|
||||||
void disableBilateralFiltering() {_bilateralFiltering = false;}
|
|
||||||
void enableIMUFiltering(int filteringStrategy=1, const ParametersMap & parameters = ParametersMap(), bool baseFrameConversion = false);
|
|
||||||
void disableIMUFiltering();
|
|
||||||
void enableFeatureDetection(const ParametersMap & parameters = ParametersMap());
|
|
||||||
void disableFeatureDetection();
|
|
||||||
|
|
||||||
// Use new version of this function with groundNormalsUp=0.8 for forceGroundNormalsUp=True and groundNormalsUp=0.0 for forceGroundNormalsUp=False.
|
|
||||||
RTABMAP_DEPRECATED void setScanParameters(
|
|
||||||
bool fromDepth,
|
|
||||||
int downsampleStep, // decimation of the depth image in case the scan is from depth image
|
|
||||||
float rangeMin,
|
|
||||||
float rangeMax,
|
|
||||||
float voxelSize,
|
|
||||||
int normalsK,
|
|
||||||
int normalsRadius,
|
|
||||||
bool forceGroundNormalsUp);
|
|
||||||
void setScanParameters(
|
|
||||||
bool fromDepth,
|
|
||||||
int downsampleStep=1, // decimation of the depth image in case the scan is from depth image
|
|
||||||
float rangeMin=0.0f,
|
|
||||||
float rangeMax=0.0f,
|
|
||||||
float voxelSize = 0.0f,
|
|
||||||
int normalsK = 0,
|
|
||||||
int normalsRadius = 0.0f,
|
|
||||||
float groundNormalsUp = 0.0f);
|
|
||||||
|
|
||||||
void postUpdate(SensorData * data, CameraInfo * info = 0) const;
|
|
||||||
|
|
||||||
//getters
|
|
||||||
bool isPaused() const {return !this->isRunning();}
|
|
||||||
bool isCapturing() const {return this->isRunning();}
|
|
||||||
bool odomProvided() const;
|
|
||||||
|
|
||||||
Camera * camera() {return _camera;} // return null if not set, valid until CameraThread is deleted
|
|
||||||
Camera * odomSensor() {return _odomSensor;} // return null if not set, valid until CameraThread is deleted
|
|
||||||
|
|
||||||
private:
|
|
||||||
virtual void mainLoopBegin();
|
|
||||||
virtual void mainLoop();
|
|
||||||
virtual void mainLoopKill();
|
|
||||||
|
|
||||||
private:
|
|
||||||
Camera * _camera;
|
|
||||||
Camera * _odomSensor;
|
|
||||||
Transform _extrinsicsOdomToCamera;
|
|
||||||
bool _odomAsGt;
|
|
||||||
double _poseTimeOffset;
|
|
||||||
float _poseScaleFactor;
|
|
||||||
bool _mirroring;
|
|
||||||
bool _stereoExposureCompensation;
|
|
||||||
bool _colorOnly;
|
|
||||||
int _imageDecimation;
|
|
||||||
int _histogramMethod;
|
|
||||||
bool _stereoToDepth;
|
|
||||||
bool _scanFromDepth;
|
|
||||||
int _scanDownsampleStep;
|
|
||||||
float _scanRangeMin;
|
|
||||||
float _scanRangeMax;
|
|
||||||
float _scanVoxelSize;
|
|
||||||
int _scanNormalsK;
|
|
||||||
float _scanNormalsRadius;
|
|
||||||
float _scanForceGroundNormalsUp;
|
|
||||||
StereoDense * _stereoDense;
|
|
||||||
clams::DiscreteDepthDistortionModel * _distortionModel;
|
|
||||||
bool _bilateralFiltering;
|
|
||||||
float _bilateralSigmaS;
|
|
||||||
float _bilateralSigmaR;
|
|
||||||
IMUFilter * _imuFilter;
|
|
||||||
bool _imuBaseFrameConversion;
|
|
||||||
Feature2D * _featureDetector;
|
|
||||||
bool _depthAsMask;
|
|
||||||
};
|
|
||||||
|
|
||||||
} // namespace rtabmap
|
|
||||||
|
|||||||
@@ -82,14 +82,15 @@ public:
|
|||||||
virtual bool isCalibrated() const;
|
virtual bool isCalibrated() const;
|
||||||
virtual std::string getSerial() const;
|
virtual std::string getSerial() const;
|
||||||
virtual bool odomProvided() const {return !_odometryIgnored;}
|
virtual bool odomProvided() const {return !_odometryIgnored;}
|
||||||
|
virtual bool getPose(double stamp, Transform & pose, cv::Mat & covariance, double maxWaitTime = 0.06);
|
||||||
|
|
||||||
const DBDriver * driver() const {return _dbDriver;}
|
const DBDriver * driver() const {return _dbDriver;}
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
virtual SensorData captureImage(CameraInfo * info = 0);
|
virtual SensorData captureImage(SensorCaptureInfo * info = 0);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
SensorData getNextData(CameraInfo * info = 0);
|
SensorData getNextData(SensorCaptureInfo * info = 0);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
std::list<std::string> _paths;
|
std::list<std::string> _paths;
|
||||||
|
|||||||
@@ -192,16 +192,17 @@ public:
|
|||||||
const cv::Mat & disparity,
|
const cv::Mat & disparity,
|
||||||
float minDisparity);
|
float minDisparity);
|
||||||
|
|
||||||
static void limitKeypoints(std::vector<cv::KeyPoint> & keypoints, int maxKeypoints);
|
static void limitKeypoints(std::vector<cv::KeyPoint> & keypoints, int maxKeypoints, const cv::Size & imageSize = cv::Size(), bool ssc = false);
|
||||||
static void limitKeypoints(std::vector<cv::KeyPoint> & keypoints, cv::Mat & descriptors, int maxKeypoints);
|
static void limitKeypoints(std::vector<cv::KeyPoint> & keypoints, cv::Mat & descriptors, int maxKeypoints, const cv::Size & imageSize = cv::Size(), bool ssc = false);
|
||||||
static void limitKeypoints(std::vector<cv::KeyPoint> & keypoints, std::vector<cv::Point3f> & keypoints3D, cv::Mat & descriptors, int maxKeypoints);
|
static void limitKeypoints(std::vector<cv::KeyPoint> & keypoints, std::vector<cv::Point3f> & keypoints3D, cv::Mat & descriptors, int maxKeypoints, const cv::Size & imageSize = cv::Size(), bool ssc = false);
|
||||||
static void limitKeypoints(const std::vector<cv::KeyPoint> & keypoints, std::vector<bool> & inliers, int maxKeypoints);
|
static void limitKeypoints(const std::vector<cv::KeyPoint> & keypoints, std::vector<bool> & inliers, int maxKeypoints, const cv::Size & imageSize = cv::Size(), bool ssc = false);
|
||||||
static void limitKeypoints(const std::vector<cv::KeyPoint> & keypoints, std::vector<bool> & inliers, int maxKeypoints, const cv::Size & imageSize, int gridRows, int gridCols);
|
static void limitKeypoints(const std::vector<cv::KeyPoint> & keypoints, std::vector<bool> & inliers, int maxKeypoints, const cv::Size & imageSize, int gridRows, int gridCols, bool ssc = false);
|
||||||
|
|
||||||
static cv::Rect computeRoi(const cv::Mat & image, const std::string & roiRatios);
|
static cv::Rect computeRoi(const cv::Mat & image, const std::string & roiRatios);
|
||||||
static cv::Rect computeRoi(const cv::Mat & image, const std::vector<float> & roiRatios);
|
static cv::Rect computeRoi(const cv::Mat & image, const std::vector<float> & roiRatios);
|
||||||
|
|
||||||
int getMaxFeatures() const {return maxFeatures_;}
|
int getMaxFeatures() const {return maxFeatures_;}
|
||||||
|
bool getSSC() const {return SSC_;}
|
||||||
float getMinDepth() const {return _minDepth;}
|
float getMinDepth() const {return _minDepth;}
|
||||||
float getMaxDepth() const {return _maxDepth;}
|
float getMaxDepth() const {return _maxDepth;}
|
||||||
int getGridRows() const {return gridRows_;}
|
int getGridRows() const {return gridRows_;}
|
||||||
@@ -234,6 +235,7 @@ private:
|
|||||||
private:
|
private:
|
||||||
ParametersMap parameters_;
|
ParametersMap parameters_;
|
||||||
int maxFeatures_;
|
int maxFeatures_;
|
||||||
|
bool SSC_;
|
||||||
float _maxDepth; // 0=inf
|
float _maxDepth; // 0=inf
|
||||||
float _minDepth;
|
float _minDepth;
|
||||||
std::vector<float> _roiRatios; // size 4
|
std::vector<float> _roiRatios; // size 4
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
Copyright (c) 2010-2020, Mathieu Labbe - IntRoLab - Universite de Sherbrooke
|
Copyright (c) 2010-2024, Mathieu Labbe - IntRoLab - Universite de Sherbrooke
|
||||||
All rights reserved.
|
All rights reserved.
|
||||||
|
|
||||||
Redistribution and use in source and binary forms, with or without
|
Redistribution and use in source and binary forms, with or without
|
||||||
|
|||||||
73
corelib/include/rtabmap/core/GlobalDescriptorExtractor.h
Normal file
73
corelib/include/rtabmap/core/GlobalDescriptorExtractor.h
Normal file
@@ -0,0 +1,73 @@
|
|||||||
|
/*
|
||||||
|
Copyright (c) 2010-2024, 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 GLOBAL_DESCRIPTOR_EXTRACTOR_H_
|
||||||
|
#define GLOBAL_DESCRIPTOR_EXTRACTOR_H_
|
||||||
|
|
||||||
|
#include "rtabmap/core/rtabmap_core_export.h" // DLL export/import defines
|
||||||
|
|
||||||
|
#include "rtabmap/core/Parameters.h"
|
||||||
|
#include "rtabmap/core/SensorData.h"
|
||||||
|
|
||||||
|
|
||||||
|
namespace rtabmap {
|
||||||
|
|
||||||
|
// Feature2D
|
||||||
|
class RTABMAP_CORE_EXPORT GlobalDescriptorExtractor {
|
||||||
|
public:
|
||||||
|
enum Type {
|
||||||
|
kUndef=0,
|
||||||
|
kPyDescriptor=1};
|
||||||
|
|
||||||
|
static std::string typeName(Type type)
|
||||||
|
{
|
||||||
|
switch(type){
|
||||||
|
case kPyDescriptor:
|
||||||
|
return "PyDescriptor";
|
||||||
|
default:
|
||||||
|
return "Unknown";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static GlobalDescriptorExtractor * create(const ParametersMap & parameters = ParametersMap());
|
||||||
|
static GlobalDescriptorExtractor * create(GlobalDescriptorExtractor::Type type, const ParametersMap & parameters = ParametersMap()); // for convenience
|
||||||
|
|
||||||
|
public:
|
||||||
|
virtual ~GlobalDescriptorExtractor();
|
||||||
|
|
||||||
|
virtual GlobalDescriptor extract(const SensorData & data) const = 0;
|
||||||
|
|
||||||
|
virtual void parseParameters(const ParametersMap & parameters) {}
|
||||||
|
virtual GlobalDescriptorExtractor::Type getType() const = 0;
|
||||||
|
|
||||||
|
protected:
|
||||||
|
GlobalDescriptorExtractor(const ParametersMap & parameters = ParametersMap());
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif /* GLOBAL_DESCRIPTOR_EXTRACTOR_H_ */
|
||||||
@@ -28,12 +28,13 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|||||||
#ifndef CORELIB_INCLUDE_RTABMAP_CORE_IMUFILTER_H_
|
#ifndef CORELIB_INCLUDE_RTABMAP_CORE_IMUFILTER_H_
|
||||||
#define CORELIB_INCLUDE_RTABMAP_CORE_IMUFILTER_H_
|
#define CORELIB_INCLUDE_RTABMAP_CORE_IMUFILTER_H_
|
||||||
|
|
||||||
|
#include "rtabmap/core/rtabmap_core_export.h" // DLL export/import defines
|
||||||
#include <rtabmap/core/Parameters.h>
|
#include <rtabmap/core/Parameters.h>
|
||||||
#include <Eigen/Geometry>
|
#include <Eigen/Geometry>
|
||||||
|
|
||||||
namespace rtabmap {
|
namespace rtabmap {
|
||||||
|
|
||||||
class IMUFilter
|
class RTABMAP_CORE_EXPORT IMUFilter
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
enum Type {
|
enum Type {
|
||||||
|
|||||||
@@ -47,7 +47,8 @@ public:
|
|||||||
kXYZRGB=7,
|
kXYZRGB=7,
|
||||||
kXYZNormal=8,
|
kXYZNormal=8,
|
||||||
kXYZINormal=9,
|
kXYZINormal=9,
|
||||||
kXYZRGBNormal=10};
|
kXYZRGBNormal=10,
|
||||||
|
kXYZIT=11};
|
||||||
|
|
||||||
static std::string formatName(const Format & format);
|
static std::string formatName(const Format & format);
|
||||||
static int channels(const Format & format);
|
static int channels(const Format & format);
|
||||||
@@ -55,6 +56,7 @@ public:
|
|||||||
static bool isScanHasNormals(const Format & format);
|
static bool isScanHasNormals(const Format & format);
|
||||||
static bool isScanHasRGB(const Format & format);
|
static bool isScanHasRGB(const Format & format);
|
||||||
static bool isScanHasIntensity(const Format & format);
|
static bool isScanHasIntensity(const Format & format);
|
||||||
|
static bool isScanHasTime(const Format & format);
|
||||||
static LaserScan backwardCompatibility(
|
static LaserScan backwardCompatibility(
|
||||||
const cv::Mat & oldScanFormat,
|
const cv::Mat & oldScanFormat,
|
||||||
int maxPoints = 0,
|
int maxPoints = 0,
|
||||||
@@ -121,22 +123,27 @@ public:
|
|||||||
float angleMin() const {return angleMin_;}
|
float angleMin() const {return angleMin_;}
|
||||||
float angleMax() const {return angleMax_;}
|
float angleMax() const {return angleMax_;}
|
||||||
float angleIncrement() const {return angleIncrement_;}
|
float angleIncrement() const {return angleIncrement_;}
|
||||||
|
void setLocalTransform(const Transform & t) {localTransform_ = t;}
|
||||||
Transform localTransform() const {return localTransform_;}
|
Transform localTransform() const {return localTransform_;}
|
||||||
|
|
||||||
bool empty() const {return data_.empty();}
|
bool empty() const {return data_.empty();}
|
||||||
bool isEmpty() const {return data_.empty();}
|
bool isEmpty() const {return data_.empty();}
|
||||||
int size() const {return data_.cols;}
|
int size() const {return data_.total();}
|
||||||
int dataType() const {return data_.type();}
|
int dataType() const {return data_.type();}
|
||||||
bool is2d() const {return isScan2d(format_);}
|
bool is2d() const {return isScan2d(format_);}
|
||||||
bool hasNormals() const {return isScanHasNormals(format_);}
|
bool hasNormals() const {return isScanHasNormals(format_);}
|
||||||
bool hasRGB() const {return isScanHasRGB(format_);}
|
bool hasRGB() const {return isScanHasRGB(format_);}
|
||||||
bool hasIntensity() const {return isScanHasIntensity(format_);}
|
bool hasIntensity() const {return isScanHasIntensity(format_);}
|
||||||
|
bool hasTime() const {return isScanHasTime(format_);}
|
||||||
bool isCompressed() const {return !data_.empty() && data_.type()==CV_8UC1;}
|
bool isCompressed() const {return !data_.empty() && data_.type()==CV_8UC1;}
|
||||||
|
bool isOrganized() const {return data_.rows > 1;}
|
||||||
LaserScan clone() const;
|
LaserScan clone() const;
|
||||||
|
LaserScan densify() const;
|
||||||
|
|
||||||
int getIntensityOffset() const {return hasIntensity()?(is2d()?2:3):-1;}
|
int getIntensityOffset() const {return hasIntensity()?(is2d()?2:3):-1;}
|
||||||
int getRGBOffset() const {return hasRGB()?(is2d()?2:3):-1;}
|
int getRGBOffset() const {return hasRGB()?(is2d()?2:3):-1;}
|
||||||
int getNormalsOffset() const {return hasNormals()?(2 + (is2d()?0:1) + ((hasRGB() || hasIntensity())?1:0)):-1;}
|
int getNormalsOffset() const {return hasNormals()?(2 + (is2d()?0:1) + ((hasRGB() || hasIntensity())?1:0)):-1;}
|
||||||
|
int getTimeOffset() const {return hasTime()?4:-1;}
|
||||||
|
|
||||||
float & field(unsigned int pointIndex, unsigned int channelOffset);
|
float & field(unsigned int pointIndex, unsigned int channelOffset);
|
||||||
|
|
||||||
|
|||||||
57
corelib/include/rtabmap/core/Lidar.h
Normal file
57
corelib/include/rtabmap/core/Lidar.h
Normal file
@@ -0,0 +1,57 @@
|
|||||||
|
/*
|
||||||
|
Copyright (c) 2010-2022, Mathieu Labbe - IntRoLab - Universite de Sherbrooke
|
||||||
|
All rights reserved.
|
||||||
|
|
||||||
|
Redistribution and use in source and binary forms, with or without
|
||||||
|
modification, are permitted provided that the following conditions are met:
|
||||||
|
* Redistributions of source code must retain the above copyright
|
||||||
|
notice, this list of conditions and the following disclaimer.
|
||||||
|
* Redistributions in binary form must reproduce the above copyright
|
||||||
|
notice, this list of conditions and the following disclaimer in the
|
||||||
|
documentation and/or other materials provided with the distribution.
|
||||||
|
* Neither the name of the Universite de Sherbrooke nor the
|
||||||
|
names of its contributors may be used to endorse or promote products
|
||||||
|
derived from this software without specific prior written permission.
|
||||||
|
|
||||||
|
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||||
|
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||||
|
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||||
|
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY
|
||||||
|
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||||
|
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||||
|
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||||
|
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||||
|
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "rtabmap/core/rtabmap_core_export.h" // DLL export/import defines
|
||||||
|
#include <rtabmap/core/SensorCapture.h>
|
||||||
|
|
||||||
|
namespace rtabmap
|
||||||
|
{
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Class Lidar
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
class RTABMAP_CORE_EXPORT Lidar : public SensorCapture
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
virtual ~Lidar() {}
|
||||||
|
|
||||||
|
protected:
|
||||||
|
/**
|
||||||
|
* Constructor
|
||||||
|
*
|
||||||
|
* @param lidarRate the frame rate (Hz), 0 for fast as the lidar can
|
||||||
|
* @param localTransform the transform from base frame to lidar frame
|
||||||
|
*/
|
||||||
|
Lidar(float lidarRate = 0, const Transform & localTransform = Transform::getIdentity()) :
|
||||||
|
SensorCapture(lidarRate, localTransform) {}
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
} // namespace rtabmap
|
||||||
@@ -59,6 +59,7 @@ class RegistrationVis;
|
|||||||
class Stereo;
|
class Stereo;
|
||||||
class LocalGridMaker;
|
class LocalGridMaker;
|
||||||
class MarkerDetector;
|
class MarkerDetector;
|
||||||
|
class GlobalDescriptorExtractor;
|
||||||
|
|
||||||
class RTABMAP_CORE_EXPORT Memory
|
class RTABMAP_CORE_EXPORT Memory
|
||||||
{
|
{
|
||||||
@@ -330,8 +331,10 @@ private:
|
|||||||
bool _rehearsalWeightIgnoredWhileMoving;
|
bool _rehearsalWeightIgnoredWhileMoving;
|
||||||
bool _useOdometryFeatures;
|
bool _useOdometryFeatures;
|
||||||
bool _useOdometryGravity;
|
bool _useOdometryGravity;
|
||||||
|
bool _rotateImagesUpsideUp;
|
||||||
bool _createOccupancyGrid;
|
bool _createOccupancyGrid;
|
||||||
int _visMaxFeatures;
|
int _visMaxFeatures;
|
||||||
|
bool _visSSC;
|
||||||
bool _imagesAlreadyRectified;
|
bool _imagesAlreadyRectified;
|
||||||
bool _rectifyOnlyFeatures;
|
bool _rectifyOnlyFeatures;
|
||||||
bool _covOffDiagonalIgnored;
|
bool _covOffDiagonalIgnored;
|
||||||
@@ -374,6 +377,8 @@ private:
|
|||||||
LocalGridMaker * _localMapMaker;
|
LocalGridMaker * _localMapMaker;
|
||||||
|
|
||||||
MarkerDetector * _markerDetector;
|
MarkerDetector * _markerDetector;
|
||||||
|
|
||||||
|
GlobalDescriptorExtractor * _globalDescriptorExtractor;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace rtabmap
|
} // namespace rtabmap
|
||||||
|
|||||||
@@ -111,6 +111,7 @@ private:
|
|||||||
bool _alignWithGround;
|
bool _alignWithGround;
|
||||||
bool _publishRAMUsage;
|
bool _publishRAMUsage;
|
||||||
bool _imagesAlreadyRectified;
|
bool _imagesAlreadyRectified;
|
||||||
|
bool _deskewing;
|
||||||
Transform _pose;
|
Transform _pose;
|
||||||
int _resetCurrentCount;
|
int _resetCurrentCount;
|
||||||
double previousStamp_;
|
double previousStamp_;
|
||||||
|
|||||||
@@ -50,6 +50,7 @@ public:
|
|||||||
localBundleConstraints(0),
|
localBundleConstraints(0),
|
||||||
localBundleTime(0),
|
localBundleTime(0),
|
||||||
keyFrameAdded(false),
|
keyFrameAdded(false),
|
||||||
|
timeDeskewing(0.0f),
|
||||||
timeEstimation(0.0f),
|
timeEstimation(0.0f),
|
||||||
timeParticleFiltering(0.0f),
|
timeParticleFiltering(0.0f),
|
||||||
stamp(0),
|
stamp(0),
|
||||||
@@ -76,6 +77,7 @@ public:
|
|||||||
output.localBundlePoses = localBundlePoses;
|
output.localBundlePoses = localBundlePoses;
|
||||||
output.localBundleModels = localBundleModels;
|
output.localBundleModels = localBundleModels;
|
||||||
output.keyFrameAdded = keyFrameAdded;
|
output.keyFrameAdded = keyFrameAdded;
|
||||||
|
output.timeDeskewing = timeDeskewing;
|
||||||
output.timeEstimation = timeEstimation;
|
output.timeEstimation = timeEstimation;
|
||||||
output.timeParticleFiltering = timeParticleFiltering;
|
output.timeParticleFiltering = timeParticleFiltering;
|
||||||
output.stamp = stamp;
|
output.stamp = stamp;
|
||||||
@@ -105,6 +107,7 @@ public:
|
|||||||
std::map<int, Transform> localBundlePoses;
|
std::map<int, Transform> localBundlePoses;
|
||||||
std::map<int, std::vector<CameraModel> > localBundleModels;
|
std::map<int, std::vector<CameraModel> > localBundleModels;
|
||||||
bool keyFrameAdded;
|
bool keyFrameAdded;
|
||||||
|
float timeDeskewing;
|
||||||
float timeEstimation;
|
float timeEstimation;
|
||||||
float timeParticleFiltering;
|
float timeParticleFiltering;
|
||||||
double stamp;
|
double stamp;
|
||||||
|
|||||||
@@ -197,6 +197,7 @@ class RTABMAP_CORE_EXPORT Parameters
|
|||||||
RTABMAP_PARAM(Rtabmap, LoopThr, float, 0.11, "Loop closing threshold.");
|
RTABMAP_PARAM(Rtabmap, LoopThr, float, 0.11, "Loop closing threshold.");
|
||||||
RTABMAP_PARAM(Rtabmap, LoopRatio, float, 0, "The loop closure hypothesis must be over LoopRatio x lastHypothesisValue.");
|
RTABMAP_PARAM(Rtabmap, LoopRatio, float, 0, "The loop closure hypothesis must be over LoopRatio x lastHypothesisValue.");
|
||||||
RTABMAP_PARAM(Rtabmap, LoopGPS, bool, true, uFormat("Use GPS to filter likelihood (if GPS is recorded). Only locations inside the local radius \"%s\" of the current GPS location are considered for loop closure detection.", kRGBDLocalRadius().c_str()));
|
RTABMAP_PARAM(Rtabmap, LoopGPS, bool, true, uFormat("Use GPS to filter likelihood (if GPS is recorded). Only locations inside the local radius \"%s\" of the current GPS location are considered for loop closure detection.", kRGBDLocalRadius().c_str()));
|
||||||
|
RTABMAP_PARAM(Rtabmap, VirtualPlaceLikelihoodRatio, int, 0, "Likelihood ratio for virtual place (for no loop closure hypothesis): 0=Mean / StdDev, 1=StdDev / (Max-Mean)");
|
||||||
|
|
||||||
// Memory
|
// Memory
|
||||||
RTABMAP_PARAM(Mem, RehearsalSimilarity, float, 0.6, "Rehearsal similarity.");
|
RTABMAP_PARAM(Mem, RehearsalSimilarity, float, 0.6, "Rehearsal similarity.");
|
||||||
@@ -231,6 +232,8 @@ class RTABMAP_CORE_EXPORT Parameters
|
|||||||
RTABMAP_PARAM(Mem, UseOdomFeatures, bool, true, "Use odometry features instead of regenerating them.");
|
RTABMAP_PARAM(Mem, UseOdomFeatures, bool, true, "Use odometry features instead of regenerating them.");
|
||||||
RTABMAP_PARAM(Mem, UseOdomGravity, bool, false, uFormat("Use odometry instead of IMU orientation to add gravity links to new nodes created. We assume that odometry is already aligned with gravity (e.g., we are using a VIO approach). Gravity constraints are used by graph optimization only if \"%s\" is not zero.", kOptimizerGravitySigma().c_str()));
|
RTABMAP_PARAM(Mem, UseOdomGravity, bool, false, uFormat("Use odometry instead of IMU orientation to add gravity links to new nodes created. We assume that odometry is already aligned with gravity (e.g., we are using a VIO approach). Gravity constraints are used by graph optimization only if \"%s\" is not zero.", kOptimizerGravitySigma().c_str()));
|
||||||
RTABMAP_PARAM(Mem, CovOffDiagIgnored, bool, true, "Ignore off diagonal values of the covariance matrix.");
|
RTABMAP_PARAM(Mem, CovOffDiagIgnored, bool, true, "Ignore off diagonal values of the covariance matrix.");
|
||||||
|
RTABMAP_PARAM(Mem, GlobalDescriptorStrategy, int, 0, "Extract global descriptor from sensor data. 0=disabled, 1=PyDescriptor");
|
||||||
|
RTABMAP_PARAM(Mem, RotateImagesUpsideUp, bool, false, "Rotate images so that upside is up if they are not already. This can be useful in case the robots don't have all same camera orientation but are using the same map, so that not rotation-invariant visual features can still be used across the fleet.");
|
||||||
|
|
||||||
// KeypointMemory (Keypoint-based)
|
// KeypointMemory (Keypoint-based)
|
||||||
RTABMAP_PARAM(Kp, NNStrategy, int, 1, "kNNFlannNaive=0, kNNFlannKdTree=1, kNNFlannLSH=2, kNNBruteForce=3, kNNBruteForceGPU=4");
|
RTABMAP_PARAM(Kp, NNStrategy, int, 1, "kNNFlannNaive=0, kNNFlannKdTree=1, kNNFlannLSH=2, kNNBruteForce=3, kNNBruteForceGPU=4");
|
||||||
@@ -241,6 +244,7 @@ class RTABMAP_CORE_EXPORT Parameters
|
|||||||
RTABMAP_PARAM(Kp, MaxDepth, float, 0, "Filter extracted keypoints by depth (0=inf).");
|
RTABMAP_PARAM(Kp, MaxDepth, float, 0, "Filter extracted keypoints by depth (0=inf).");
|
||||||
RTABMAP_PARAM(Kp, MinDepth, float, 0, "Filter extracted keypoints by depth.");
|
RTABMAP_PARAM(Kp, MinDepth, float, 0, "Filter extracted keypoints by depth.");
|
||||||
RTABMAP_PARAM(Kp, MaxFeatures, int, 500, "Maximum features extracted from the images (0 means not bounded, <0 means no extraction).");
|
RTABMAP_PARAM(Kp, MaxFeatures, int, 500, "Maximum features extracted from the images (0 means not bounded, <0 means no extraction).");
|
||||||
|
RTABMAP_PARAM(Kp, SSC, bool, false, "If true, SSC (Suppression via Square Covering) is applied to limit keypoints.");
|
||||||
RTABMAP_PARAM(Kp, BadSignRatio, float, 0.5, "Bad signature ratio (less than Ratio x AverageWordsPerImage = bad).");
|
RTABMAP_PARAM(Kp, BadSignRatio, float, 0.5, "Bad signature ratio (less than Ratio x AverageWordsPerImage = bad).");
|
||||||
RTABMAP_PARAM(Kp, NndrRatio, float, 0.8, "NNDR ratio (A matching pair is detected, if its distance is closer than X times the distance of the second nearest neighbor.)");
|
RTABMAP_PARAM(Kp, NndrRatio, float, 0.8, "NNDR ratio (A matching pair is detected, if its distance is closer than X times the distance of the second nearest neighbor.)");
|
||||||
#if CV_MAJOR_VERSION > 2 && !defined(HAVE_OPENCV_XFEATURES2D)
|
#if CV_MAJOR_VERSION > 2 && !defined(HAVE_OPENCV_XFEATURES2D)
|
||||||
@@ -353,10 +357,12 @@ class RTABMAP_CORE_EXPORT Parameters
|
|||||||
RTABMAP_PARAM(RGBD, AngularUpdate, float, 0.1, "Minimum angular displacement (rad) to update the map. Rehearsal is done prior to this, so weights are still updated.");
|
RTABMAP_PARAM(RGBD, AngularUpdate, float, 0.1, "Minimum angular displacement (rad) to update the map. Rehearsal is done prior to this, so weights are still updated.");
|
||||||
RTABMAP_PARAM(RGBD, LinearSpeedUpdate, float, 0.0, "Maximum linear speed (m/s) to update the map (0 means not limit).");
|
RTABMAP_PARAM(RGBD, LinearSpeedUpdate, float, 0.0, "Maximum linear speed (m/s) to update the map (0 means not limit).");
|
||||||
RTABMAP_PARAM(RGBD, AngularSpeedUpdate, float, 0.0, "Maximum angular speed (rad/s) to update the map (0 means not limit).");
|
RTABMAP_PARAM(RGBD, AngularSpeedUpdate, float, 0.0, "Maximum angular speed (rad/s) to update the map (0 means not limit).");
|
||||||
|
RTABMAP_PARAM(RGBD, AggressiveLoopThr, float, 0.05, uFormat("Loop closure threshold used (overriding %s) when a new mapping session is not yet linked to a map of the highest loop closure hypothesis. In localization mode, this threshold is used when there are no loop closure constraints with any map in the cache (%s). In all cases, the goal is to aggressively loop on a previous map in the database. Only used when %s is enabled. Set 1 to disable.", kRtabmapLoopThr().c_str(), kRGBDMaxOdomCacheSize().c_str(), kRGBDEnabled().c_str()));
|
||||||
RTABMAP_PARAM(RGBD, NewMapOdomChangeDistance, float, 0, "A new map is created if a change of odometry translation greater than X m is detected (0 m = disabled).");
|
RTABMAP_PARAM(RGBD, NewMapOdomChangeDistance, float, 0, "A new map is created if a change of odometry translation greater than X m is detected (0 m = disabled).");
|
||||||
RTABMAP_PARAM(RGBD, OptimizeFromGraphEnd, bool, false, "Optimize graph from the newest node. If false, the graph is optimized from the oldest node of the current graph (this adds an overhead computation to detect to oldest node of the current graph, but it can be useful to preserve the map referential from the oldest node). Warning when set to false: when some nodes are transferred, the first referential of the local map may change, resulting in momentary changes in robot/map position (which are annoying in teleoperation).");
|
RTABMAP_PARAM(RGBD, OptimizeFromGraphEnd, bool, false, "Optimize graph from the newest node. If false, the graph is optimized from the oldest node of the current graph (this adds an overhead computation to detect to oldest node of the current graph, but it can be useful to preserve the map referential from the oldest node). Warning when set to false: when some nodes are transferred, the first referential of the local map may change, resulting in momentary changes in robot/map position (which are annoying in teleoperation).");
|
||||||
RTABMAP_PARAM(RGBD, OptimizeMaxError, float, 3.0, uFormat("Reject loop closures if optimization error ratio is greater than this value (0=disabled). Ratio is computed as absolute error over standard deviation of each link. This will help to detect when a wrong loop closure is added to the graph. Not compatible with \"%s\" if enabled.", kOptimizerRobust().c_str()));
|
RTABMAP_PARAM(RGBD, OptimizeMaxError, float, 3.0, uFormat("Reject loop closures if optimization error ratio is greater than this value (0=disabled). Ratio is computed as absolute error over standard deviation of each link. This will help to detect when a wrong loop closure is added to the graph. Not compatible with \"%s\" if enabled.", kOptimizerRobust().c_str()));
|
||||||
RTABMAP_PARAM(RGBD, MaxLoopClosureDistance, float, 0.0, "Reject loop closures/localizations if the distance from the map is over this distance (0=disabled).");
|
RTABMAP_PARAM(RGBD, MaxLoopClosureDistance, float, 0.0, "Reject loop closures/localizations if the distance from the map is over this distance (0=disabled).");
|
||||||
|
RTABMAP_PARAM(RGBD, ForceOdom3DoF, bool, true, uFormat("Force odometry pose to be 3DoF if %s=true.", kRegForce3DoF().c_str()));
|
||||||
RTABMAP_PARAM(RGBD, StartAtOrigin, bool, false, uFormat("If true, rtabmap will assume the robot is starting from origin of the map. If false, rtabmap will assume the robot is restarting from the last saved localization pose from previous session (the place where it shut down previously). Used only in localization mode (%s=false).", kMemIncrementalMemory().c_str()));
|
RTABMAP_PARAM(RGBD, StartAtOrigin, bool, false, uFormat("If true, rtabmap will assume the robot is starting from origin of the map. If false, rtabmap will assume the robot is restarting from the last saved localization pose from previous session (the place where it shut down previously). Used only in localization mode (%s=false).", kMemIncrementalMemory().c_str()));
|
||||||
RTABMAP_PARAM(RGBD, GoalReachedRadius, float, 0.5, "Goal reached radius (m).");
|
RTABMAP_PARAM(RGBD, GoalReachedRadius, float, 0.5, "Goal reached radius (m).");
|
||||||
RTABMAP_PARAM(RGBD, PlanStuckIterations, int, 0, "Mark the current goal node on the path as unreachable if it is not updated after X iterations (0=disabled). If all upcoming nodes on the path are unreachabled, the plan fails.");
|
RTABMAP_PARAM(RGBD, PlanStuckIterations, int, 0, "Mark the current goal node on the path as unreachable if it is not updated after X iterations (0=disabled). If all upcoming nodes on the path are unreachabled, the plan fails.");
|
||||||
@@ -435,6 +441,9 @@ class RTABMAP_CORE_EXPORT Parameters
|
|||||||
RTABMAP_PARAM(g2o, Baseline, double, 0.075, "When doing bundle adjustment with RGB-D data, we can set a fake baseline (m) to do stereo bundle adjustment (if 0, mono bundle adjustment is done). For stereo data, the baseline in the calibration is used directly.");
|
RTABMAP_PARAM(g2o, Baseline, double, 0.075, "When doing bundle adjustment with RGB-D data, we can set a fake baseline (m) to do stereo bundle adjustment (if 0, mono bundle adjustment is done). For stereo data, the baseline in the calibration is used directly.");
|
||||||
|
|
||||||
RTABMAP_PARAM(GTSAM, Optimizer, int, 1, "0=Levenberg 1=GaussNewton 2=Dogleg");
|
RTABMAP_PARAM(GTSAM, Optimizer, int, 1, "0=Levenberg 1=GaussNewton 2=Dogleg");
|
||||||
|
RTABMAP_PARAM(GTSAM, Incremental, bool, false, uFormat("Do graph optimization incrementally (iSAM2) to increase optimization speed on loop closures. Note that only GaussNewton and Dogleg optimization algorithms are supported (%s) in this mode.", kGTSAMOptimizer().c_str()));
|
||||||
|
RTABMAP_PARAM(GTSAM, IncRelinearizeThreshold, double, 0.01, "Only relinearize variables whose linear delta magnitude is greater than this threshold. See GTSAM::ISAM2 doc for more info.");
|
||||||
|
RTABMAP_PARAM(GTSAM, IncRelinearizeSkip, int, 1, "Only relinearize any variables every X calls to ISAM2::update(). See GTSAM::ISAM2 doc for more info.");
|
||||||
|
|
||||||
// Odometry
|
// Odometry
|
||||||
RTABMAP_PARAM(Odom, Strategy, int, 0, "0=Frame-to-Map (F2M) 1=Frame-to-Frame (F2F) 2=Fovis 3=viso2 4=DVO-SLAM 5=ORB_SLAM2 6=OKVIS 7=LOAM 8=MSCKF_VIO 9=VINS-Fusion 10=OpenVINS 11=FLOAM 12=Open3D");
|
RTABMAP_PARAM(Odom, Strategy, int, 0, "0=Frame-to-Map (F2M) 1=Frame-to-Frame (F2F) 2=Fovis 3=viso2 4=DVO-SLAM 5=ORB_SLAM2 6=OKVIS 7=LOAM 8=MSCKF_VIO 9=VINS-Fusion 10=OpenVINS 11=FLOAM 12=Open3D");
|
||||||
@@ -457,6 +466,7 @@ class RTABMAP_CORE_EXPORT Parameters
|
|||||||
RTABMAP_PARAM(Odom, ScanKeyFrameThr, float, 0.9, "[Geometry] Create a new keyframe when the number of ICP inliers drops under this ratio of points in last frame's scan. Setting the value to 0 means that a keyframe is created for each processed frame.");
|
RTABMAP_PARAM(Odom, ScanKeyFrameThr, float, 0.9, "[Geometry] Create a new keyframe when the number of ICP inliers drops under this ratio of points in last frame's scan. Setting the value to 0 means that a keyframe is created for each processed frame.");
|
||||||
RTABMAP_PARAM(Odom, ImageDecimation, unsigned int, 1, uFormat("Decimation of the RGB image before registration. If depth size is larger than decimated RGB size, depth is decimated to be always at most equal to RGB size. If %s is true and if depth is smaller than decimated RGB, depth may be interpolated to match RGB size for feature detection.", kVisDepthAsMask().c_str()));
|
RTABMAP_PARAM(Odom, ImageDecimation, unsigned int, 1, uFormat("Decimation of the RGB image before registration. If depth size is larger than decimated RGB size, depth is decimated to be always at most equal to RGB size. If %s is true and if depth is smaller than decimated RGB, depth may be interpolated to match RGB size for feature detection.", kVisDepthAsMask().c_str()));
|
||||||
RTABMAP_PARAM(Odom, AlignWithGround, bool, false, "Align odometry with the ground on initialization.");
|
RTABMAP_PARAM(Odom, AlignWithGround, bool, false, "Align odometry with the ground on initialization.");
|
||||||
|
RTABMAP_PARAM(Odom, Deskewing, bool, true, "Lidar deskewing. If input lidar has time channel, it will be deskewed with a constant motion model (with IMU orientation and/or guess if provided).");
|
||||||
|
|
||||||
// Odometry Frame-to-Map
|
// Odometry Frame-to-Map
|
||||||
RTABMAP_PARAM(OdomF2M, MaxSize, int, 2000, "[Visual] Local map size: If > 0 (example 5000), the odometry will maintain a local map of X maximum words.");
|
RTABMAP_PARAM(OdomF2M, MaxSize, int, 2000, "[Visual] Local map size: If > 0 (example 5000), the odometry will maintain a local map of X maximum words.");
|
||||||
@@ -670,6 +680,7 @@ class RTABMAP_CORE_EXPORT Parameters
|
|||||||
RTABMAP_PARAM(Vis, PnPVarianceMedianRatio, int, 4, uFormat("[%s = 1] Ratio used to compute variance of the estimated transformation if 3D correspondences are provided (should be > 1). The higher it is, the smaller the covariance will be. With accurate depth estimation, this could be set to 2. For depth estimated by stereo, 4 or more maybe used to ignore large errors of very far points.", kVisEstimationType().c_str()));
|
RTABMAP_PARAM(Vis, PnPVarianceMedianRatio, int, 4, uFormat("[%s = 1] Ratio used to compute variance of the estimated transformation if 3D correspondences are provided (should be > 1). The higher it is, the smaller the covariance will be. With accurate depth estimation, this could be set to 2. For depth estimated by stereo, 4 or more maybe used to ignore large errors of very far points.", kVisEstimationType().c_str()));
|
||||||
RTABMAP_PARAM(Vis, PnPMaxVariance, float, 0.0, uFormat("[%s = 1] Max linear variance between 3D point correspondences after PnP. 0 means disabled.", kVisEstimationType().c_str()));
|
RTABMAP_PARAM(Vis, PnPMaxVariance, float, 0.0, uFormat("[%s = 1] Max linear variance between 3D point correspondences after PnP. 0 means disabled.", kVisEstimationType().c_str()));
|
||||||
RTABMAP_PARAM(Vis, PnPSamplingPolicy, unsigned int, 1, uFormat("[%s = 1] Multi-camera random sampling policy: 0=AUTO, 1=ANY, 2=HOMOGENEOUS. With HOMOGENEOUS policy, RANSAC will be done uniformly against all cameras, so at least 2 matches per camera are required. With ANY policy, RANSAC is not constraint to sample on all cameras at the same time. AUTO policy will use HOMOGENEOUS if there are at least 2 matches per camera, otherwise it will fallback to ANY policy.", kVisEstimationType().c_str()).c_str());
|
RTABMAP_PARAM(Vis, PnPSamplingPolicy, unsigned int, 1, uFormat("[%s = 1] Multi-camera random sampling policy: 0=AUTO, 1=ANY, 2=HOMOGENEOUS. With HOMOGENEOUS policy, RANSAC will be done uniformly against all cameras, so at least 2 matches per camera are required. With ANY policy, RANSAC is not constraint to sample on all cameras at the same time. AUTO policy will use HOMOGENEOUS if there are at least 2 matches per camera, otherwise it will fallback to ANY policy.", kVisEstimationType().c_str()).c_str());
|
||||||
|
RTABMAP_PARAM(Vis, PnPSplitLinearCovComponents, bool, false, uFormat("[%s = 1] Compute variance for each linear component instead of using the combined XYZ variance for all linear components.", kVisEstimationType().c_str()).c_str());
|
||||||
|
|
||||||
RTABMAP_PARAM(Vis, EpipolarGeometryVar, float, 0.1, uFormat("[%s = 2] Epipolar geometry maximum variance to accept the transformation.", kVisEstimationType().c_str()));
|
RTABMAP_PARAM(Vis, EpipolarGeometryVar, float, 0.1, uFormat("[%s = 2] Epipolar geometry maximum variance to accept the transformation.", kVisEstimationType().c_str()));
|
||||||
RTABMAP_PARAM(Vis, MinInliers, int, 20, "Minimum feature correspondences to compute/accept the transformation.");
|
RTABMAP_PARAM(Vis, MinInliers, int, 20, "Minimum feature correspondences to compute/accept the transformation.");
|
||||||
@@ -684,6 +695,7 @@ class RTABMAP_CORE_EXPORT Parameters
|
|||||||
RTABMAP_PARAM(Vis, FeatureType, int, 6, "0=SURF 1=SIFT 2=ORB 3=FAST/FREAK 4=FAST/BRIEF 5=GFTT/FREAK 6=GFTT/BRIEF 7=BRISK 8=GFTT/ORB 9=KAZE 10=ORB-OCTREE 11=SuperPoint 12=SURF/FREAK 13=GFTT/DAISY 14=SURF/DAISY 15=PyDetector");
|
RTABMAP_PARAM(Vis, FeatureType, int, 6, "0=SURF 1=SIFT 2=ORB 3=FAST/FREAK 4=FAST/BRIEF 5=GFTT/FREAK 6=GFTT/BRIEF 7=BRISK 8=GFTT/ORB 9=KAZE 10=ORB-OCTREE 11=SuperPoint 12=SURF/FREAK 13=GFTT/DAISY 14=SURF/DAISY 15=PyDetector");
|
||||||
#endif
|
#endif
|
||||||
RTABMAP_PARAM(Vis, MaxFeatures, int, 1000, "0 no limits.");
|
RTABMAP_PARAM(Vis, MaxFeatures, int, 1000, "0 no limits.");
|
||||||
|
RTABMAP_PARAM(Vis, SSC, bool, false, "If true, SSC (Suppression via Square Covering) is applied to limit keypoints.");
|
||||||
RTABMAP_PARAM(Vis, MaxDepth, float, 0, "Max depth of the features (0 means no limit).");
|
RTABMAP_PARAM(Vis, MaxDepth, float, 0, "Max depth of the features (0 means no limit).");
|
||||||
RTABMAP_PARAM(Vis, MinDepth, float, 0, "Min depth of the features (0 means no limit).");
|
RTABMAP_PARAM(Vis, MinDepth, float, 0, "Min depth of the features (0 means no limit).");
|
||||||
RTABMAP_PARAM(Vis, DepthAsMask, bool, true, "Use depth image as mask when extracting features.");
|
RTABMAP_PARAM(Vis, DepthAsMask, bool, true, "Use depth image as mask when extracting features.");
|
||||||
@@ -719,6 +731,10 @@ class RTABMAP_CORE_EXPORT Parameters
|
|||||||
RTABMAP_PARAM(GMS, WithScale, bool, false, "Take scale transformation into account.");
|
RTABMAP_PARAM(GMS, WithScale, bool, false, "Take scale transformation into account.");
|
||||||
RTABMAP_PARAM(GMS, ThresholdFactor, double, 6.0, "The higher, the less matches.");
|
RTABMAP_PARAM(GMS, ThresholdFactor, double, 6.0, "The higher, the less matches.");
|
||||||
|
|
||||||
|
// Global descriptor approaches
|
||||||
|
RTABMAP_PARAM_STR(PyDescriptor, Path, "", "Path to python script file (see available ones in rtabmap/corelib/src/pydescriptor/*). See the header to see where the script should be used.");
|
||||||
|
RTABMAP_PARAM(PyDescriptor, Dim, int, 4096, "Descriptor dimension.");
|
||||||
|
|
||||||
// ICP registration parameters
|
// ICP registration parameters
|
||||||
#ifdef RTABMAP_POINTMATCHER
|
#ifdef RTABMAP_POINTMATCHER
|
||||||
RTABMAP_PARAM(Icp, Strategy, int, 1, "ICP implementation: 0=Point Cloud Library, 1=libpointmatcher, 2=CCCoreLib (CloudCompare).");
|
RTABMAP_PARAM(Icp, Strategy, int, 1, "ICP implementation: 0=Point Cloud Library, 1=libpointmatcher, 2=CCCoreLib (CloudCompare).");
|
||||||
@@ -741,6 +757,7 @@ class RTABMAP_CORE_EXPORT Parameters
|
|||||||
RTABMAP_PARAM(Icp, Epsilon, float, 0, "Set the transformation epsilon (maximum allowable difference between two consecutive transformations) in order for an optimization to be considered as having converged to the final solution.");
|
RTABMAP_PARAM(Icp, Epsilon, float, 0, "Set the transformation epsilon (maximum allowable difference between two consecutive transformations) in order for an optimization to be considered as having converged to the final solution.");
|
||||||
RTABMAP_PARAM(Icp, CorrespondenceRatio, float, 0.1, "Ratio of matching correspondences to accept the transform.");
|
RTABMAP_PARAM(Icp, CorrespondenceRatio, float, 0.1, "Ratio of matching correspondences to accept the transform.");
|
||||||
RTABMAP_PARAM(Icp, Force4DoF, bool, false, uFormat("Limit ICP to x, y, z and yaw DoF. Available if %s > 0.", kIcpStrategy().c_str()));
|
RTABMAP_PARAM(Icp, Force4DoF, bool, false, uFormat("Limit ICP to x, y, z and yaw DoF. Available if %s > 0.", kIcpStrategy().c_str()));
|
||||||
|
RTABMAP_PARAM(Icp, FiltersEnabled, int, 3, "Flag to enable filters: 1=\"from\" cloud only, 2=\"to\" cloud only, 3=both.");
|
||||||
#ifdef RTABMAP_POINTMATCHER
|
#ifdef RTABMAP_POINTMATCHER
|
||||||
RTABMAP_PARAM(Icp, PointToPlane, bool, true, "Use point to plane ICP.");
|
RTABMAP_PARAM(Icp, PointToPlane, bool, true, "Use point to plane ICP.");
|
||||||
#else
|
#else
|
||||||
@@ -920,6 +937,7 @@ public:
|
|||||||
static ParametersMap filterParameters(const ParametersMap & parameters, const std::string & group, bool remove = false);
|
static ParametersMap filterParameters(const ParametersMap & parameters, const std::string & group, bool remove = false);
|
||||||
|
|
||||||
static void readINI(const std::string & configFile, ParametersMap & parameters, bool modifiedOnly = false);
|
static void readINI(const std::string & configFile, ParametersMap & parameters, bool modifiedOnly = false);
|
||||||
|
static void readINIStr(const std::string & configContent, ParametersMap & parameters, bool modifiedOnly = false);
|
||||||
static void writeINI(const std::string & configFile, const ParametersMap & parameters);
|
static void writeINI(const std::string & configFile, const ParametersMap & parameters);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -69,6 +69,7 @@ private:
|
|||||||
float _epsilon;
|
float _epsilon;
|
||||||
float _correspondenceRatio;
|
float _correspondenceRatio;
|
||||||
bool _force4DoF;
|
bool _force4DoF;
|
||||||
|
int _filtersEnabled;
|
||||||
bool _pointToPlane;
|
bool _pointToPlane;
|
||||||
int _pointToPlaneK;
|
int _pointToPlaneK;
|
||||||
float _pointToPlaneRadius;
|
float _pointToPlaneRadius;
|
||||||
|
|||||||
@@ -84,6 +84,7 @@ private:
|
|||||||
int _PnPRefineIterations;
|
int _PnPRefineIterations;
|
||||||
int _PnPVarMedianRatio;
|
int _PnPVarMedianRatio;
|
||||||
float _PnPMaxVar;
|
float _PnPMaxVar;
|
||||||
|
bool _PnPSplitLinearCovarianceComponents;
|
||||||
unsigned int _multiSamplingPolicy;
|
unsigned int _multiSamplingPolicy;
|
||||||
int _correspondencesApproach;
|
int _correspondencesApproach;
|
||||||
int _flowWinSize;
|
int _flowWinSize;
|
||||||
|
|||||||
@@ -151,6 +151,8 @@ public:
|
|||||||
|
|
||||||
float getTimeThreshold() const {return _maxTimeAllowed;} // in ms
|
float getTimeThreshold() const {return _maxTimeAllowed;} // in ms
|
||||||
void setTimeThreshold(float maxTimeAllowed); // in ms
|
void setTimeThreshold(float maxTimeAllowed); // in ms
|
||||||
|
int getMemoryThreshold() const {return _maxMemoryAllowed;} // in nodes
|
||||||
|
void setMemoryThreshold(int maxMemoryAllowed); // in nodes
|
||||||
|
|
||||||
void setInitialPose(const Transform & initialPose);
|
void setInitialPose(const Transform & initialPose);
|
||||||
int triggerNewMap();
|
int triggerNewMap();
|
||||||
@@ -282,6 +284,8 @@ private:
|
|||||||
unsigned int _maxMemoryAllowed; // signatures count in WM
|
unsigned int _maxMemoryAllowed; // signatures count in WM
|
||||||
float _loopThr;
|
float _loopThr;
|
||||||
float _loopRatio;
|
float _loopRatio;
|
||||||
|
float _aggressiveLoopThr;
|
||||||
|
int _virtualPlaceLikelihoodRatio;
|
||||||
float _maxLoopClosureDistance;
|
float _maxLoopClosureDistance;
|
||||||
bool _verifyLoopClosureHypothesis;
|
bool _verifyLoopClosureHypothesis;
|
||||||
unsigned int _maxRetrieved;
|
unsigned int _maxRetrieved;
|
||||||
@@ -322,6 +326,7 @@ private:
|
|||||||
int _pathStuckIterations;
|
int _pathStuckIterations;
|
||||||
float _pathLinearVelocity;
|
float _pathLinearVelocity;
|
||||||
float _pathAngularVelocity;
|
float _pathAngularVelocity;
|
||||||
|
bool _forceOdom3doF;
|
||||||
bool _restartAtOrigin;
|
bool _restartAtOrigin;
|
||||||
bool _loopCovLimited;
|
bool _loopCovLimited;
|
||||||
bool _loopGPS;
|
bool _loopGPS;
|
||||||
|
|||||||
93
corelib/include/rtabmap/core/SensorCapture.h
Normal file
93
corelib/include/rtabmap/core/SensorCapture.h
Normal file
@@ -0,0 +1,93 @@
|
|||||||
|
/*
|
||||||
|
Copyright (c) 2010-2022, Mathieu Labbe
|
||||||
|
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 names of its contributors may be used to endorse or promote products
|
||||||
|
derived from this software without specific prior written permission.
|
||||||
|
|
||||||
|
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||||
|
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||||
|
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||||
|
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY
|
||||||
|
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||||
|
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||||
|
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||||
|
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||||
|
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "rtabmap/core/rtabmap_core_export.h" // DLL export/import defines
|
||||||
|
|
||||||
|
#include <opencv2/highgui/highgui.hpp>
|
||||||
|
#include <rtabmap/core/SensorCaptureInfo.h>
|
||||||
|
#include "rtabmap/core/SensorData.h"
|
||||||
|
#include <set>
|
||||||
|
#include <stack>
|
||||||
|
#include <list>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
|
class UDirectory;
|
||||||
|
class UTimer;
|
||||||
|
|
||||||
|
namespace rtabmap
|
||||||
|
{
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Class Camera
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
class RTABMAP_CORE_EXPORT SensorCapture
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
virtual ~SensorCapture();
|
||||||
|
SensorData takeData(SensorCaptureInfo * info = 0);
|
||||||
|
|
||||||
|
virtual bool init(const std::string & calibrationFolder = ".", const std::string & cameraName = "") = 0;
|
||||||
|
virtual std::string getSerial() const = 0;
|
||||||
|
virtual bool odomProvided() const { return false; }
|
||||||
|
virtual bool getPose(double stamp, Transform & pose, cv::Mat & covariance, double maxWaitTime = 0.06) { return false; }
|
||||||
|
|
||||||
|
//getters
|
||||||
|
float getFrameRate() const {return _frameRate;}
|
||||||
|
const Transform & getLocalTransform() const {return _localTransform;}
|
||||||
|
|
||||||
|
//setters
|
||||||
|
void setFrameRate(float frameRate) {_frameRate = frameRate;}
|
||||||
|
void setLocalTransform(const Transform & localTransform) {_localTransform= localTransform;}
|
||||||
|
|
||||||
|
void resetTimer();
|
||||||
|
protected:
|
||||||
|
/**
|
||||||
|
* Constructor
|
||||||
|
*
|
||||||
|
* @param frameRate the frame rate (Hz), 0 for fast as the sensor can
|
||||||
|
* @param localTransform the transform from base frame to sensor frame
|
||||||
|
*/
|
||||||
|
SensorCapture(float frameRate = 0, const Transform & localTransform = Transform::getIdentity());
|
||||||
|
|
||||||
|
/**
|
||||||
|
* returned rgb and depth images should be already rectified if calibration was loaded
|
||||||
|
*/
|
||||||
|
virtual SensorData captureData(SensorCaptureInfo * info = 0) = 0;
|
||||||
|
|
||||||
|
int getNextSeqID() {return ++_seq;}
|
||||||
|
|
||||||
|
private:
|
||||||
|
float _frameRate;
|
||||||
|
Transform _localTransform;
|
||||||
|
UTimer * _frameRateTimer;
|
||||||
|
int _seq;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
} // namespace rtabmap
|
||||||
82
corelib/include/rtabmap/core/SensorCaptureInfo.h
Normal file
82
corelib/include/rtabmap/core/SensorCaptureInfo.h
Normal file
@@ -0,0 +1,82 @@
|
|||||||
|
/*
|
||||||
|
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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "rtabmap/core/Transform.h"
|
||||||
|
#include <string>
|
||||||
|
|
||||||
|
namespace rtabmap
|
||||||
|
{
|
||||||
|
|
||||||
|
class SensorCaptureInfo
|
||||||
|
{
|
||||||
|
|
||||||
|
public:
|
||||||
|
SensorCaptureInfo() :
|
||||||
|
cameraName(""),
|
||||||
|
id(0),
|
||||||
|
stamp(0.0),
|
||||||
|
timeCapture(0.0f),
|
||||||
|
timeDeskewing(0.0f),
|
||||||
|
timeDisparity(0.0f),
|
||||||
|
timeMirroring(0.0f),
|
||||||
|
timeStereoExposureCompensation(0.0f),
|
||||||
|
timeImageDecimation(0.0f),
|
||||||
|
timeHistogramEqualization(0.0f),
|
||||||
|
timeScanFromDepth(0.0f),
|
||||||
|
timeUndistortDepth(0.0f),
|
||||||
|
timeBilateralFiltering(0.0f),
|
||||||
|
timeTotal(0.0f),
|
||||||
|
odomCovariance(cv::Mat::eye(6,6,CV_64FC1))
|
||||||
|
{
|
||||||
|
}
|
||||||
|
virtual ~SensorCaptureInfo() {}
|
||||||
|
|
||||||
|
std::string cameraName;
|
||||||
|
int id;
|
||||||
|
double stamp;
|
||||||
|
float timeCapture;
|
||||||
|
float timeDeskewing;
|
||||||
|
float timeDisparity;
|
||||||
|
float timeMirroring;
|
||||||
|
float timeStereoExposureCompensation;
|
||||||
|
float timeImageDecimation;
|
||||||
|
float timeHistogramEqualization;
|
||||||
|
float timeScanFromDepth;
|
||||||
|
float timeUndistortDepth;
|
||||||
|
float timeBilateralFiltering;
|
||||||
|
float timeTotal;
|
||||||
|
Transform odomPose;
|
||||||
|
cv::Mat odomCovariance;
|
||||||
|
std::vector<float> odomVelocity;
|
||||||
|
};
|
||||||
|
|
||||||
|
//backward compatibility
|
||||||
|
RTABMAP_DEPRECATED typedef SensorCaptureInfo CameraInfo;
|
||||||
|
|
||||||
|
} // namespace rtabmap
|
||||||
216
corelib/include/rtabmap/core/SensorCaptureThread.h
Normal file
216
corelib/include/rtabmap/core/SensorCaptureThread.h
Normal file
@@ -0,0 +1,216 @@
|
|||||||
|
/*
|
||||||
|
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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "rtabmap/core/rtabmap_core_export.h" // DLL export/import defines
|
||||||
|
|
||||||
|
#include <rtabmap/core/Parameters.h>
|
||||||
|
#include <rtabmap/core/Transform.h>
|
||||||
|
#include <rtabmap/utilite/UThread.h>
|
||||||
|
#include <rtabmap/utilite/UEventsSender.h>
|
||||||
|
|
||||||
|
namespace clams
|
||||||
|
{
|
||||||
|
class DiscreteDepthDistortionModel;
|
||||||
|
}
|
||||||
|
|
||||||
|
namespace rtabmap
|
||||||
|
{
|
||||||
|
|
||||||
|
class Camera;
|
||||||
|
class Lidar;
|
||||||
|
class SensorCapture;
|
||||||
|
class SensorCaptureInfo;
|
||||||
|
class SensorData;
|
||||||
|
class StereoDense;
|
||||||
|
class IMUFilter;
|
||||||
|
class Feature2D;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Class CameraThread
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
class RTABMAP_CORE_EXPORT SensorCaptureThread :
|
||||||
|
public UThread,
|
||||||
|
public UEventsSender
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
// ownership transferred
|
||||||
|
SensorCaptureThread(
|
||||||
|
Camera * camera,
|
||||||
|
const ParametersMap & parameters = ParametersMap());
|
||||||
|
/**
|
||||||
|
* @param camera the camera to take images from
|
||||||
|
* @param odomSensor an odometry sensor to get a pose (can be again the camera)
|
||||||
|
* @param odomAsGt set odometry sensor pose as ground truth instead of odometry
|
||||||
|
* @param extrinsics the static transform between odometry sensor's left lens frame to camera's left lens frame (without optical rotation)
|
||||||
|
*/
|
||||||
|
SensorCaptureThread(
|
||||||
|
Camera * camera,
|
||||||
|
SensorCapture * odomSensor,
|
||||||
|
const Transform & extrinsics,
|
||||||
|
double poseTimeOffset = 0.0,
|
||||||
|
float poseScaleFactor = 1.0f,
|
||||||
|
double poseWaitTime = 0.1,
|
||||||
|
const ParametersMap & parameters = ParametersMap());
|
||||||
|
/**
|
||||||
|
* @param lidar the lidar to take scans from
|
||||||
|
*/
|
||||||
|
SensorCaptureThread(
|
||||||
|
Lidar * lidar,
|
||||||
|
const ParametersMap & parameters = ParametersMap());
|
||||||
|
/**
|
||||||
|
* @param lidar the lidar to take scans from
|
||||||
|
* @param camera the camera to take images from. If the camera is providing a pose, it can be used for deskewing
|
||||||
|
*/
|
||||||
|
SensorCaptureThread(
|
||||||
|
Lidar * lidar,
|
||||||
|
Camera * camera,
|
||||||
|
const ParametersMap & parameters = ParametersMap());
|
||||||
|
/**
|
||||||
|
* @param lidar the lidar to take scans from
|
||||||
|
* @param odomSensor an odometry sensor to get a pose and used for deskewing (can be again the lidar)
|
||||||
|
*/
|
||||||
|
SensorCaptureThread(
|
||||||
|
Lidar * lidar,
|
||||||
|
SensorCapture * odomSensor,
|
||||||
|
double poseTimeOffset = 0.0,
|
||||||
|
float poseScaleFactor = 1.0f,
|
||||||
|
double poseWaitTime = 0.1,
|
||||||
|
const ParametersMap & parameters = ParametersMap());
|
||||||
|
/**
|
||||||
|
* @param lidar the lidar to take scans from
|
||||||
|
* @param camera the camera to take images from
|
||||||
|
* @param odomSensor an odometry sensor to get a pose and used for deskewing (can be again the camera or lidar)
|
||||||
|
* @param extrinsics the static transform between odometry frame to camera frame (without optical rotation)
|
||||||
|
*/
|
||||||
|
SensorCaptureThread(
|
||||||
|
Lidar * lidar,
|
||||||
|
Camera * camera,
|
||||||
|
SensorCapture * odomSensor,
|
||||||
|
const Transform & extrinsics,
|
||||||
|
double poseTimeOffset = 0.0,
|
||||||
|
float poseScaleFactor = 1.0f,
|
||||||
|
double poseWaitTime = 0.1,
|
||||||
|
const ParametersMap & parameters = ParametersMap());
|
||||||
|
virtual ~SensorCaptureThread();
|
||||||
|
|
||||||
|
void setMirroringEnabled(bool enabled) {_mirroring = enabled;}
|
||||||
|
void setStereoExposureCompensation(bool enabled) {_stereoExposureCompensation = enabled;}
|
||||||
|
void setColorOnly(bool colorOnly) {_colorOnly = colorOnly;}
|
||||||
|
void setImageDecimation(int decimation) {_imageDecimation = decimation;}
|
||||||
|
void setHistogramMethod(int histogramMethod) {_histogramMethod = histogramMethod;}
|
||||||
|
void setStereoToDepth(bool enabled) {_stereoToDepth = enabled;}
|
||||||
|
void setFrameRate(float frameRate);
|
||||||
|
RTABMAP_DEPRECATED void setImageRate(float frameRate) {setFrameRate(frameRate);}
|
||||||
|
void setDistortionModel(const std::string & path);
|
||||||
|
void setOdomAsGroundTruth(bool enabled) {_odomAsGt = enabled;}
|
||||||
|
void enableBilateralFiltering(float sigmaS, float sigmaR);
|
||||||
|
void disableBilateralFiltering() {_bilateralFiltering = false;}
|
||||||
|
void enableIMUFiltering(int filteringStrategy=1, const ParametersMap & parameters = ParametersMap(), bool baseFrameConversion = false);
|
||||||
|
void disableIMUFiltering();
|
||||||
|
void enableFeatureDetection(const ParametersMap & parameters = ParametersMap());
|
||||||
|
void disableFeatureDetection();
|
||||||
|
|
||||||
|
// Use new version of this function with groundNormalsUp=0.8 for forceGroundNormalsUp=True and groundNormalsUp=0.0 for forceGroundNormalsUp=False.
|
||||||
|
RTABMAP_DEPRECATED void setScanParameters(
|
||||||
|
bool fromDepth,
|
||||||
|
int downsampleStep, // decimation of the depth image in case the scan is from depth image
|
||||||
|
float rangeMin,
|
||||||
|
float rangeMax,
|
||||||
|
float voxelSize,
|
||||||
|
int normalsK,
|
||||||
|
float normalsRadius,
|
||||||
|
bool forceGroundNormalsUp,
|
||||||
|
bool deskewing);
|
||||||
|
void setScanParameters(
|
||||||
|
bool fromDepth,
|
||||||
|
int downsampleStep=1, // decimation of the depth image in case the scan is from depth image
|
||||||
|
float rangeMin=0.0f,
|
||||||
|
float rangeMax=0.0f,
|
||||||
|
float voxelSize = 0.0f,
|
||||||
|
int normalsK = 0,
|
||||||
|
float normalsRadius = 0.0f,
|
||||||
|
float groundNormalsUp = 0.0f,
|
||||||
|
bool deskewing = false);
|
||||||
|
|
||||||
|
void postUpdate(SensorData * data, SensorCaptureInfo * info = 0) const;
|
||||||
|
|
||||||
|
//getters
|
||||||
|
bool isPaused() const {return !this->isRunning();}
|
||||||
|
bool isCapturing() const {return this->isRunning();}
|
||||||
|
bool odomProvided() const;
|
||||||
|
|
||||||
|
Camera * camera() {return _camera;} // return null if not set, valid until CameraThread is deleted
|
||||||
|
SensorCapture * odomSensor() {return _odomSensor;} // return null if not set, valid until CameraThread is deleted
|
||||||
|
Lidar * lidar() {return _lidar;} // return null if not set, valid until CameraThread is deleted
|
||||||
|
|
||||||
|
private:
|
||||||
|
virtual void mainLoopBegin();
|
||||||
|
virtual void mainLoop();
|
||||||
|
virtual void mainLoopKill();
|
||||||
|
|
||||||
|
private:
|
||||||
|
Camera * _camera;
|
||||||
|
SensorCapture * _odomSensor;
|
||||||
|
Lidar * _lidar;
|
||||||
|
Transform _extrinsicsOdomToCamera;
|
||||||
|
bool _odomAsGt;
|
||||||
|
double _poseTimeOffset;
|
||||||
|
float _poseScaleFactor;
|
||||||
|
double _poseWaitTime;
|
||||||
|
bool _mirroring;
|
||||||
|
bool _stereoExposureCompensation;
|
||||||
|
bool _colorOnly;
|
||||||
|
int _imageDecimation;
|
||||||
|
int _histogramMethod;
|
||||||
|
bool _stereoToDepth;
|
||||||
|
bool _scanDeskewing;
|
||||||
|
bool _scanFromDepth;
|
||||||
|
int _scanDownsampleStep;
|
||||||
|
float _scanRangeMin;
|
||||||
|
float _scanRangeMax;
|
||||||
|
float _scanVoxelSize;
|
||||||
|
int _scanNormalsK;
|
||||||
|
float _scanNormalsRadius;
|
||||||
|
float _scanForceGroundNormalsUp;
|
||||||
|
StereoDense * _stereoDense;
|
||||||
|
clams::DiscreteDepthDistortionModel * _distortionModel;
|
||||||
|
bool _bilateralFiltering;
|
||||||
|
float _bilateralSigmaS;
|
||||||
|
float _bilateralSigmaR;
|
||||||
|
IMUFilter * _imuFilter;
|
||||||
|
bool _imuBaseFrameConversion;
|
||||||
|
Feature2D * _featureDetector;
|
||||||
|
bool _depthAsMask;
|
||||||
|
};
|
||||||
|
|
||||||
|
//backward compatibility
|
||||||
|
RTABMAP_DEPRECATED typedef SensorCaptureThread CameraThread;
|
||||||
|
|
||||||
|
} // namespace rtabmap
|
||||||
94
corelib/include/rtabmap/core/SensorEvent.h
Normal file
94
corelib/include/rtabmap/core/SensorEvent.h
Normal file
@@ -0,0 +1,94 @@
|
|||||||
|
/*
|
||||||
|
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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <rtabmap/core/SensorCaptureInfo.h>
|
||||||
|
#include <rtabmap/utilite/UEvent.h>
|
||||||
|
#include "rtabmap/core/SensorData.h"
|
||||||
|
|
||||||
|
namespace rtabmap
|
||||||
|
{
|
||||||
|
|
||||||
|
class SensorEvent :
|
||||||
|
public UEvent
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
enum Code {
|
||||||
|
kCodeData,
|
||||||
|
kCodeNoMoreImages
|
||||||
|
};
|
||||||
|
|
||||||
|
public:
|
||||||
|
SensorEvent(const cv::Mat & image, int seq=0, double stamp = 0.0, const std::string & cameraName = std::string()) :
|
||||||
|
UEvent(kCodeData),
|
||||||
|
data_(image, seq, stamp)
|
||||||
|
{
|
||||||
|
sensorCaptureInfo_.cameraName = cameraName;
|
||||||
|
}
|
||||||
|
|
||||||
|
SensorEvent() :
|
||||||
|
UEvent(kCodeNoMoreImages)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
SensorEvent(const SensorData & data) :
|
||||||
|
UEvent(kCodeData),
|
||||||
|
data_(data)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
SensorEvent(const SensorData & data, const std::string & cameraName) :
|
||||||
|
UEvent(kCodeData),
|
||||||
|
data_(data)
|
||||||
|
{
|
||||||
|
sensorCaptureInfo_.cameraName = cameraName;
|
||||||
|
}
|
||||||
|
SensorEvent(const SensorData & data, const SensorCaptureInfo & sensorCaptureInfo) :
|
||||||
|
UEvent(kCodeData),
|
||||||
|
data_(data),
|
||||||
|
sensorCaptureInfo_(sensorCaptureInfo)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
// Image or descriptors
|
||||||
|
const SensorData & data() const {return data_;}
|
||||||
|
const std::string & cameraName() const {return sensorCaptureInfo_.cameraName;}
|
||||||
|
const SensorCaptureInfo & info() const {return sensorCaptureInfo_;}
|
||||||
|
|
||||||
|
virtual ~SensorEvent() {}
|
||||||
|
virtual std::string getClassName() const {return std::string("SensorEvent");}
|
||||||
|
|
||||||
|
private:
|
||||||
|
SensorData data_;
|
||||||
|
SensorCaptureInfo sensorCaptureInfo_;
|
||||||
|
};
|
||||||
|
|
||||||
|
//backward compatibility
|
||||||
|
RTABMAP_DEPRECATED typedef SensorEvent CameraEvent;
|
||||||
|
|
||||||
|
} // namespace rtabmap
|
||||||
@@ -90,9 +90,10 @@ public:
|
|||||||
void removeLink(int idTo);
|
void removeLink(int idTo);
|
||||||
void removeVirtualLinks();
|
void removeVirtualLinks();
|
||||||
|
|
||||||
void addLandmark(const Link & landmark) {_landmarks.insert(std::make_pair(landmark.to(), landmark));}
|
void addLandmark(const Link & landmark);
|
||||||
const std::map<int, Link> & getLandmarks() const {return _landmarks;}
|
const std::map<int, Link> & getLandmarks() const {return _landmarks;}
|
||||||
void removeLandmarks() {_landmarks.clear();}
|
void removeLandmarks();
|
||||||
|
void removeLandmark(int landmarkId);
|
||||||
|
|
||||||
void setSaved(bool saved) {_saved = saved;}
|
void setSaved(bool saved) {_saved = saved;}
|
||||||
void setModified(bool modified) {_modified = modified; _linksModified = modified;}
|
void setModified(bool modified) {_modified = modified; _linksModified = modified;}
|
||||||
|
|||||||
@@ -157,6 +157,7 @@ class RTABMAP_CORE_EXPORT Statistics
|
|||||||
RTABMAP_STATS(Timing, Memory_update, ms);
|
RTABMAP_STATS(Timing, Memory_update, ms);
|
||||||
RTABMAP_STATS(Timing, Neighbor_link_refining, ms);
|
RTABMAP_STATS(Timing, Neighbor_link_refining, ms);
|
||||||
RTABMAP_STATS(Timing, Proximity_by_time, ms);
|
RTABMAP_STATS(Timing, Proximity_by_time, ms);
|
||||||
|
RTABMAP_STATS(Timing, Proximity_by_space_search, ms);
|
||||||
RTABMAP_STATS(Timing, Proximity_by_space_visual, ms);
|
RTABMAP_STATS(Timing, Proximity_by_space_visual, ms);
|
||||||
RTABMAP_STATS(Timing, Proximity_by_space, ms);
|
RTABMAP_STATS(Timing, Proximity_by_space, ms);
|
||||||
RTABMAP_STATS(Timing, Cleaning_neighbors, ms);
|
RTABMAP_STATS(Timing, Cleaning_neighbors, ms);
|
||||||
|
|||||||
@@ -57,9 +57,12 @@ public:
|
|||||||
|
|
||||||
void setOutputMode(int outputMode = 0);
|
void setOutputMode(int outputMode = 0);
|
||||||
void setDepthProfile(int confThreshold = 200, int lrcThreshold = 5);
|
void setDepthProfile(int confThreshold = 200, int lrcThreshold = 5);
|
||||||
void setRectification(bool useSpecTranslation, float alphaScaling = 0.0f);
|
void setExtendedDisparity(bool extendedDisparity);
|
||||||
|
void setSubpixelMode(bool enabled, int fractionalBits = 3);
|
||||||
|
void setCompanding(bool enabled, int width=96);
|
||||||
|
void setRectification(bool useSpecTranslation, float alphaScaling = 0.0f, bool enabled=true);
|
||||||
void setIMU(bool imuPublished, bool publishInterIMU);
|
void setIMU(bool imuPublished, bool publishInterIMU);
|
||||||
void setIrBrightness(float dotProjectormA = 0.0f, float floodLightmA = 200.0f);
|
void setIrIntensity(float dotIntensity = 0.0f, float floodIntensity = 0.0f);
|
||||||
void setDetectFeatures(int detectFeatures = 0);
|
void setDetectFeatures(int detectFeatures = 0);
|
||||||
void setBlobPath(const std::string & blobPath);
|
void setBlobPath(const std::string & blobPath);
|
||||||
void setGFTTDetector(bool useHarrisDetector = false, float minDistance = 7.0f, int numTargetFeatures = 1000);
|
void setGFTTDetector(bool useHarrisDetector = false, float minDistance = 7.0f, int numTargetFeatures = 1000);
|
||||||
@@ -70,7 +73,7 @@ public:
|
|||||||
virtual std::string getSerial() const;
|
virtual std::string getSerial() const;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
virtual SensorData captureImage(CameraInfo * info = 0);
|
virtual SensorData captureImage(SensorCaptureInfo * info = 0);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
#ifdef RTABMAP_DEPTHAI
|
#ifdef RTABMAP_DEPTHAI
|
||||||
@@ -82,12 +85,16 @@ private:
|
|||||||
int confThreshold_;
|
int confThreshold_;
|
||||||
int lrcThreshold_;
|
int lrcThreshold_;
|
||||||
int resolution_;
|
int resolution_;
|
||||||
|
bool extendedDisparity_;
|
||||||
|
int subpixelFractionalBits_;
|
||||||
|
int compandingWidth_;
|
||||||
bool useSpecTranslation_;
|
bool useSpecTranslation_;
|
||||||
float alphaScaling_;
|
float alphaScaling_;
|
||||||
|
bool imagesRectified_;
|
||||||
bool imuPublished_;
|
bool imuPublished_;
|
||||||
bool publishInterIMU_;
|
bool publishInterIMU_;
|
||||||
float dotProjectormA_;
|
float dotIntensity_;
|
||||||
float floodLightmA_;
|
float floodIntensity_;
|
||||||
int detectFeatures_;
|
int detectFeatures_;
|
||||||
bool useHarrisDetector_;
|
bool useHarrisDetector_;
|
||||||
float minDistance_;
|
float minDistance_;
|
||||||
@@ -97,9 +104,7 @@ private:
|
|||||||
int nmsRadius_;
|
int nmsRadius_;
|
||||||
std::string blobPath_;
|
std::string blobPath_;
|
||||||
std::shared_ptr<dai::Device> device_;
|
std::shared_ptr<dai::Device> device_;
|
||||||
std::shared_ptr<dai::DataOutputQueue> leftOrColorQueue_;
|
std::shared_ptr<dai::DataOutputQueue> cameraQueue_;
|
||||||
std::shared_ptr<dai::DataOutputQueue> rightOrDepthQueue_;
|
|
||||||
std::shared_ptr<dai::DataOutputQueue> featuresQueue_;
|
|
||||||
std::map<double, cv::Vec3f> accBuffer_;
|
std::map<double, cv::Vec3f> accBuffer_;
|
||||||
std::map<double, cv::Vec3f> gyroBuffer_;
|
std::map<double, cv::Vec3f> gyroBuffer_;
|
||||||
UMutex imuMutex_;
|
UMutex imuMutex_;
|
||||||
|
|||||||
@@ -61,7 +61,7 @@ public:
|
|||||||
virtual std::string getSerial() const;
|
virtual std::string getSerial() const;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
virtual SensorData captureImage(CameraInfo * info = 0);
|
virtual SensorData captureImage(SensorCaptureInfo * info = 0);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
#ifdef RTABMAP_FREENECT
|
#ifdef RTABMAP_FREENECT
|
||||||
|
|||||||
@@ -77,7 +77,7 @@ public:
|
|||||||
virtual std::string getSerial() const;
|
virtual std::string getSerial() const;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
virtual SensorData captureImage(CameraInfo * info = 0);
|
virtual SensorData captureImage(SensorCaptureInfo * info = 0);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
#ifdef RTABMAP_FREENECT2
|
#ifdef RTABMAP_FREENECT2
|
||||||
|
|||||||
@@ -118,7 +118,7 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
virtual SensorData captureImage(CameraInfo * info = 0);
|
virtual SensorData captureImage(SensorCaptureInfo * info = 0);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
bool readPoses(
|
bool readPoses(
|
||||||
|
|||||||
@@ -63,7 +63,7 @@ public:
|
|||||||
void setPreferences(int rgb_resolution, int framerate, int depth_resolution);
|
void setPreferences(int rgb_resolution, int framerate, int depth_resolution);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
virtual SensorData captureImage(CameraInfo * info = 0);
|
virtual SensorData captureImage(SensorCaptureInfo * info = 0);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void close();
|
void close();
|
||||||
|
|||||||
@@ -72,7 +72,7 @@ public:
|
|||||||
virtual std::string getSerial() const;
|
virtual std::string getSerial() const;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
virtual SensorData captureImage(CameraInfo * info = 0);
|
virtual SensorData captureImage(SensorCaptureInfo * info = 0);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void close();
|
void close();
|
||||||
|
|||||||
@@ -67,7 +67,7 @@ protected:
|
|||||||
/**
|
/**
|
||||||
* returned rgb and depth images should be already rectified if calibration was loaded
|
* returned rgb and depth images should be already rectified if calibration was loaded
|
||||||
*/
|
*/
|
||||||
virtual SensorData captureImage(CameraInfo * info = 0);
|
virtual SensorData captureImage(SensorCaptureInfo * info = 0);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
#ifdef RTABMAP_MYNTEYE
|
#ifdef RTABMAP_MYNTEYE
|
||||||
|
|||||||
@@ -69,7 +69,7 @@ public:
|
|||||||
void setDepthDecimation(int decimation);
|
void setDepthDecimation(int decimation);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
virtual SensorData captureImage(CameraInfo * info = 0);
|
virtual SensorData captureImage(SensorCaptureInfo * info = 0);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
#ifdef RTABMAP_OPENNI2
|
#ifdef RTABMAP_OPENNI2
|
||||||
|
|||||||
@@ -51,7 +51,7 @@ public:
|
|||||||
virtual std::string getSerial() const {return "";} // unknown with OpenCV
|
virtual std::string getSerial() const {return "";} // unknown with OpenCV
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
virtual SensorData captureImage(CameraInfo * info = 0);
|
virtual SensorData captureImage(SensorCaptureInfo * info = 0);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
bool _asus;
|
bool _asus;
|
||||||
|
|||||||
@@ -34,15 +34,13 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|||||||
|
|
||||||
#include <pcl/pcl_config.h>
|
#include <pcl/pcl_config.h>
|
||||||
|
|
||||||
#ifdef HAVE_OPENNI
|
#ifdef RTABMAP_OPENNI
|
||||||
#if __linux__ && __i386__ && __cplusplus >= 201103L
|
#if __linux__ && __i386__ && __cplusplus >= 201103L
|
||||||
#warning "Openni driver is not available on i386 when building with c++11 support"
|
#warning "Openni driver is not available on i386 when building with c++11 support"
|
||||||
#else
|
#endif
|
||||||
#define RTABMAP_OPENNI
|
|
||||||
#include <pcl/io/openni_camera/openni_depth_image.h>
|
#include <pcl/io/openni_camera/openni_depth_image.h>
|
||||||
#include <pcl/io/openni_camera/openni_image.h>
|
#include <pcl/io/openni_camera/openni_image.h>
|
||||||
#endif
|
#endif
|
||||||
#endif
|
|
||||||
|
|
||||||
#include <boost/signals2/connection.hpp>
|
#include <boost/signals2/connection.hpp>
|
||||||
|
|
||||||
@@ -74,7 +72,7 @@ public:
|
|||||||
float constant);
|
float constant);
|
||||||
#else
|
#else
|
||||||
void image_cb (
|
void image_cb (
|
||||||
const boost::shared_ptr<openni_wrapper::Image>& rgb,
|
const boost::shared_ptr<openni_wrapper::Image>& rgb,
|
||||||
const boost::shared_ptr<openni_wrapper::DepthImage>& depth,
|
const boost::shared_ptr<openni_wrapper::DepthImage>& depth,
|
||||||
float constant);
|
float constant);
|
||||||
#endif
|
#endif
|
||||||
@@ -85,7 +83,7 @@ public:
|
|||||||
virtual std::string getSerial() const;
|
virtual std::string getSerial() const;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
virtual SensorData captureImage(CameraInfo * info = 0);
|
virtual SensorData captureImage(SensorCaptureInfo * info = 0);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
pcl::Grabber* interface_;
|
pcl::Grabber* interface_;
|
||||||
|
|||||||
@@ -53,7 +53,7 @@ public:
|
|||||||
virtual void setMaxFrames(int value) {CameraImages::setMaxFrames(value);cameraDepth_.setMaxFrames(value);}
|
virtual void setMaxFrames(int value) {CameraImages::setMaxFrames(value);cameraDepth_.setMaxFrames(value);}
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
virtual SensorData captureImage(CameraInfo * info = 0);
|
virtual SensorData captureImage(SensorCaptureInfo * info = 0);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
CameraImages cameraDepth_;
|
CameraImages cameraDepth_;
|
||||||
|
|||||||
@@ -72,7 +72,7 @@ public:
|
|||||||
virtual bool odomProvided() const;
|
virtual bool odomProvided() const;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
virtual SensorData captureImage(CameraInfo * info = 0);
|
virtual SensorData captureImage(SensorCaptureInfo * info = 0);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
#ifdef RTABMAP_REALSENSE
|
#ifdef RTABMAP_REALSENSE
|
||||||
|
|||||||
@@ -68,7 +68,7 @@ public:
|
|||||||
virtual bool isCalibrated() const;
|
virtual bool isCalibrated() const;
|
||||||
virtual std::string getSerial() const;
|
virtual std::string getSerial() const;
|
||||||
virtual bool odomProvided() const;
|
virtual bool odomProvided() const;
|
||||||
virtual bool getPose(double stamp, Transform & pose, cv::Mat & covariance);
|
virtual bool getPose(double stamp, Transform & pose, cv::Mat & covariance, double maxWaitTime = 0.06);
|
||||||
|
|
||||||
// parameters are set during initialization
|
// parameters are set during initialization
|
||||||
// D400 series
|
// D400 series
|
||||||
@@ -77,7 +77,7 @@ public:
|
|||||||
void setResolution(int width, int height, int fps = 30);
|
void setResolution(int width, int height, int fps = 30);
|
||||||
void setDepthResolution(int width, int height, int fps = 30);
|
void setDepthResolution(int width, int height, int fps = 30);
|
||||||
void setGlobalTimeSync(bool enabled);
|
void setGlobalTimeSync(bool enabled);
|
||||||
void publishInterIMU(bool enabled);
|
|
||||||
/**
|
/**
|
||||||
* Dual mode (D400+T265 or L500+T265)
|
* Dual mode (D400+T265 or L500+T265)
|
||||||
* @param enabled enable dual mode
|
* @param enabled enable dual mode
|
||||||
@@ -105,7 +105,7 @@ private:
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
virtual SensorData captureImage(CameraInfo * info = 0);
|
virtual SensorData captureImage(SensorCaptureInfo * info = 0);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
#ifdef RTABMAP_REALSENSE2
|
#ifdef RTABMAP_REALSENSE2
|
||||||
@@ -142,7 +142,6 @@ private:
|
|||||||
int cameraDepthHeight_;
|
int cameraDepthHeight_;
|
||||||
int cameraDepthFps_;
|
int cameraDepthFps_;
|
||||||
bool globalTimeSync_;
|
bool globalTimeSync_;
|
||||||
bool publishInterIMU_;
|
|
||||||
bool dualMode_;
|
bool dualMode_;
|
||||||
Transform dualExtrinsics_;
|
Transform dualExtrinsics_;
|
||||||
std::string jsonConfig_;
|
std::string jsonConfig_;
|
||||||
|
|||||||
52
corelib/include/rtabmap/core/camera/CameraSeerSense.h
Normal file
52
corelib/include/rtabmap/core/camera/CameraSeerSense.h
Normal file
@@ -0,0 +1,52 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "rtabmap/core/Camera.h"
|
||||||
|
#include "rtabmap/core/Version.h"
|
||||||
|
#include "rtabmap/utilite/USemaphore.h"
|
||||||
|
|
||||||
|
#ifdef RTABMAP_XVSDK
|
||||||
|
#include <xv-sdk.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
namespace rtabmap
|
||||||
|
{
|
||||||
|
|
||||||
|
class RTABMAP_CORE_EXPORT CameraSeerSense :
|
||||||
|
public Camera
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
static bool available();
|
||||||
|
|
||||||
|
public:
|
||||||
|
CameraSeerSense(
|
||||||
|
bool computeOdometry = false,
|
||||||
|
float imageRate = 0.0f,
|
||||||
|
const Transform & localTransform = Transform::getIdentity()
|
||||||
|
);
|
||||||
|
virtual ~CameraSeerSense();
|
||||||
|
|
||||||
|
virtual bool init(const std::string & calibrationFolder = ".", const std::string & cameraName = "");
|
||||||
|
virtual bool isCalibrated() const;
|
||||||
|
virtual std::string getSerial() const;
|
||||||
|
virtual bool odomProvided() const;
|
||||||
|
virtual bool getPose(double stamp, Transform & pose, cv::Mat & covariance, double maxWaitTime = 0.0);
|
||||||
|
|
||||||
|
protected:
|
||||||
|
virtual SensorData captureImage(SensorCaptureInfo * info = 0);
|
||||||
|
|
||||||
|
private:
|
||||||
|
#ifdef RTABMAP_XVSDK
|
||||||
|
CameraModel cameraModel_;
|
||||||
|
bool computeOdometry_;
|
||||||
|
int imuId_;
|
||||||
|
int tofId_;
|
||||||
|
std::shared_ptr<xv::Device> device_;
|
||||||
|
std::map<double, std::pair<cv::Vec3d, cv::Vec3d>> imuBuffer_;
|
||||||
|
std::pair<double, std::pair<cv::Mat, cv::Mat>> lastData_;
|
||||||
|
UMutex imuMutex_;
|
||||||
|
UMutex dataMutex_;
|
||||||
|
USemaphore dataReady_;
|
||||||
|
#endif
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace rtabmap
|
||||||
@@ -51,7 +51,7 @@ public:
|
|||||||
virtual std::string getSerial() const;
|
virtual std::string getSerial() const;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
virtual SensorData captureImage(CameraInfo * info = 0);
|
virtual SensorData captureImage(SensorCaptureInfo * info = 0);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
#ifdef RTABMAP_DC1394
|
#ifdef RTABMAP_DC1394
|
||||||
|
|||||||
@@ -53,7 +53,7 @@ public:
|
|||||||
virtual std::string getSerial() const;
|
virtual std::string getSerial() const;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
virtual SensorData captureImage(CameraInfo * info = 0);
|
virtual SensorData captureImage(SensorCaptureInfo * info = 0);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
#ifdef RTABMAP_FLYCAPTURE2
|
#ifdef RTABMAP_FLYCAPTURE2
|
||||||
|
|||||||
@@ -64,7 +64,7 @@ public:
|
|||||||
virtual void setMaxFrames(int value) {CameraImages::setMaxFrames(value);camera2_->setMaxFrames(value);}
|
virtual void setMaxFrames(int value) {CameraImages::setMaxFrames(value);camera2_->setMaxFrames(value);}
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
virtual SensorData captureImage(CameraInfo * info = 0);
|
virtual SensorData captureImage(SensorCaptureInfo * info = 0);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
CameraImages * camera2_;
|
CameraImages * camera2_;
|
||||||
|
|||||||
@@ -60,7 +60,7 @@ public:
|
|||||||
virtual std::string getSerial() const;
|
virtual std::string getSerial() const;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
virtual SensorData captureImage(CameraInfo * info = 0);
|
virtual SensorData captureImage(SensorCaptureInfo * info = 0);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
cv::VideoCapture capture_;
|
cv::VideoCapture capture_;
|
||||||
|
|||||||
@@ -71,7 +71,7 @@ public:
|
|||||||
void setResolution(int width, int height) {_width=width, _height=height;}
|
void setResolution(int width, int height) {_width=width, _height=height;}
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
virtual SensorData captureImage(CameraInfo * info = 0);
|
virtual SensorData captureImage(SensorCaptureInfo * info = 0);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
cv::VideoCapture capture_;
|
cv::VideoCapture capture_;
|
||||||
|
|||||||
@@ -76,12 +76,12 @@ public:
|
|||||||
virtual bool isCalibrated() const;
|
virtual bool isCalibrated() const;
|
||||||
virtual std::string getSerial() const;
|
virtual std::string getSerial() const;
|
||||||
virtual bool odomProvided() const;
|
virtual bool odomProvided() const;
|
||||||
virtual bool getPose(double stamp, Transform & pose, cv::Mat & covariance);
|
virtual bool getPose(double stamp, Transform & pose, cv::Mat & covariance, double maxWaitTime = 0.0);
|
||||||
|
|
||||||
void publishInterIMU(bool enabled);
|
void postInterIMUPublic(const IMU & imu, double stamp);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
virtual SensorData captureImage(CameraInfo * info = 0);
|
virtual SensorData captureImage(SensorCaptureInfo * info = 0);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
#ifdef RTABMAP_ZED
|
#ifdef RTABMAP_ZED
|
||||||
@@ -100,7 +100,6 @@ private:
|
|||||||
bool computeOdometry_;
|
bool computeOdometry_;
|
||||||
bool lost_;
|
bool lost_;
|
||||||
bool force3DoF_;
|
bool force3DoF_;
|
||||||
bool publishInterIMU_;
|
|
||||||
ZedIMUThread * imuPublishingThread_;
|
ZedIMUThread * imuPublishingThread_;
|
||||||
#endif
|
#endif
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -63,7 +63,7 @@ public:
|
|||||||
virtual std::string getSerial() const;
|
virtual std::string getSerial() const;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
virtual SensorData captureImage(CameraInfo * info = 0);
|
virtual SensorData captureImage(SensorCaptureInfo * info = 0);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
#ifdef RTABMAP_ZEDOC
|
#ifdef RTABMAP_ZEDOC
|
||||||
|
|||||||
@@ -64,7 +64,7 @@ public:
|
|||||||
void setResolution(int width, int height) {_width=width, _height=height;}
|
void setResolution(int width, int height) {_width=width, _height=height;}
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
virtual SensorData captureImage(CameraInfo * info = 0);
|
virtual SensorData captureImage(SensorCaptureInfo * info = 0);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
// File type
|
// File type
|
||||||
|
|||||||
94
corelib/include/rtabmap/core/lidar/LidarVLP16.h
Normal file
94
corelib/include/rtabmap/core/lidar/LidarVLP16.h
Normal file
@@ -0,0 +1,94 @@
|
|||||||
|
/*
|
||||||
|
Copyright (c) 2010-2022, Mathieu Labbe
|
||||||
|
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 names of its contributors may be used to endorse or promote products
|
||||||
|
derived from this software without specific prior written permission.
|
||||||
|
|
||||||
|
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||||
|
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||||
|
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||||
|
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY
|
||||||
|
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||||
|
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||||
|
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||||
|
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||||
|
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*/
|
||||||
|
#ifndef CORELIB_INCLUDE_RTABMAP_CORE_LIDAR_LIDARVLP16_H_
|
||||||
|
#define CORELIB_INCLUDE_RTABMAP_CORE_LIDAR_LIDARVLP16_H_
|
||||||
|
|
||||||
|
// Should be first on windows to avoid "WinSock.h has already been included" error
|
||||||
|
#include <pcl/io/vlp_grabber.h>
|
||||||
|
|
||||||
|
#include <rtabmap/core/Lidar.h>
|
||||||
|
#include <rtabmap/utilite/USemaphore.h>
|
||||||
|
|
||||||
|
namespace rtabmap {
|
||||||
|
|
||||||
|
struct PointXYZIT {
|
||||||
|
float x;
|
||||||
|
float y;
|
||||||
|
float z;
|
||||||
|
float i;
|
||||||
|
float t;
|
||||||
|
};
|
||||||
|
|
||||||
|
class RTABMAP_CORE_EXPORT LidarVLP16 :public Lidar, public pcl::VLPGrabber {
|
||||||
|
public:
|
||||||
|
LidarVLP16(
|
||||||
|
const std::string& pcapFile,
|
||||||
|
bool organized = false,
|
||||||
|
bool stampLast = true,
|
||||||
|
float frameRate = 0.0f,
|
||||||
|
Transform localTransform = Transform::getIdentity());
|
||||||
|
LidarVLP16(
|
||||||
|
const boost::asio::ip::address& ipAddress,
|
||||||
|
const std::uint16_t port = 2368,
|
||||||
|
bool organized = false,
|
||||||
|
bool useHostTime = true,
|
||||||
|
bool stampLast = true,
|
||||||
|
float frameRate = 0.0f,
|
||||||
|
Transform localTransform = Transform::getIdentity());
|
||||||
|
virtual ~LidarVLP16();
|
||||||
|
|
||||||
|
SensorData takeScan(SensorCaptureInfo * info = 0) {return takeData(info);}
|
||||||
|
|
||||||
|
virtual bool init(const std::string & calibrationFolder = ".", const std::string & cameraName = "") override;
|
||||||
|
virtual std::string getSerial() const override {return getName();}
|
||||||
|
|
||||||
|
void setOrganized(bool enable);
|
||||||
|
|
||||||
|
private:
|
||||||
|
void buildTimings(bool dualMode);
|
||||||
|
virtual void toPointClouds (HDLDataPacket *dataPacket) override;
|
||||||
|
|
||||||
|
protected:
|
||||||
|
virtual SensorData captureData(SensorCaptureInfo * info = 0) override;
|
||||||
|
|
||||||
|
private:
|
||||||
|
// timing offset lookup table
|
||||||
|
std::vector< std::vector<float> > timingOffsets_;
|
||||||
|
bool timingOffsetsDualMode_;
|
||||||
|
double startSweepTime_;
|
||||||
|
double startSweepTimeHost_;
|
||||||
|
bool organized_;
|
||||||
|
bool useHostTime_;
|
||||||
|
bool stampLast_;
|
||||||
|
SensorData lastScan_;
|
||||||
|
std::vector<std::vector<PointXYZIT> > accumulatedScans_;
|
||||||
|
USemaphore scanReady_;
|
||||||
|
UMutex lastScanMutex_;
|
||||||
|
};
|
||||||
|
|
||||||
|
} /* namespace rtabmap */
|
||||||
|
|
||||||
|
#endif /* CORELIB_INCLUDE_RTABMAP_CORE_LIDAR_LIDARVLP16_H_ */
|
||||||
@@ -49,7 +49,7 @@ public:
|
|||||||
private:
|
private:
|
||||||
virtual Transform computeTransform(SensorData & image, const Transform & guess = Transform(), OdometryInfo * info = 0);
|
virtual Transform computeTransform(SensorData & image, const Transform & guess = Transform(), OdometryInfo * info = 0);
|
||||||
|
|
||||||
bool init(const rtabmap::CameraModel & model, double stamp, bool stereo, double baseline);
|
bool init(const rtabmap::CameraModel & model1, const rtabmap::CameraModel & model2, double stamp, bool stereo, double baseline);
|
||||||
private:
|
private:
|
||||||
#if defined(RTABMAP_ORB_SLAM) and RTABMAP_ORB_SLAM == 3
|
#if defined(RTABMAP_ORB_SLAM) and RTABMAP_ORB_SLAM == 3
|
||||||
ORB_SLAM3::System * orbslam_;
|
ORB_SLAM3::System * orbslam_;
|
||||||
|
|||||||
@@ -30,6 +30,10 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|||||||
|
|
||||||
#include <rtabmap/core/Optimizer.h>
|
#include <rtabmap/core/Optimizer.h>
|
||||||
|
|
||||||
|
namespace gtsam {
|
||||||
|
class ISAM2;
|
||||||
|
}
|
||||||
|
|
||||||
namespace rtabmap {
|
namespace rtabmap {
|
||||||
|
|
||||||
class RTABMAP_CORE_EXPORT OptimizerGTSAM : public Optimizer
|
class RTABMAP_CORE_EXPORT OptimizerGTSAM : public Optimizer
|
||||||
@@ -38,13 +42,8 @@ public:
|
|||||||
static bool available();
|
static bool available();
|
||||||
|
|
||||||
public:
|
public:
|
||||||
OptimizerGTSAM(const ParametersMap & parameters = ParametersMap()) :
|
OptimizerGTSAM(const ParametersMap & parameters = ParametersMap());
|
||||||
Optimizer(parameters),
|
virtual ~OptimizerGTSAM();
|
||||||
optimizer_(Parameters::defaultGTSAMOptimizer())
|
|
||||||
{
|
|
||||||
parseParameters(parameters);
|
|
||||||
}
|
|
||||||
virtual ~OptimizerGTSAM() {}
|
|
||||||
|
|
||||||
virtual Type type() const {return kTypeGTSAM;}
|
virtual Type type() const {return kTypeGTSAM;}
|
||||||
|
|
||||||
@@ -60,7 +59,25 @@ public:
|
|||||||
int * iterationsDone = 0);
|
int * iterationsDone = 0);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
int optimizer_;
|
int internalOptimizerType_;
|
||||||
|
|
||||||
|
gtsam::ISAM2 * isam2_;
|
||||||
|
struct ConstraintToFactor {
|
||||||
|
ConstraintToFactor(int _from, int _to, std::uint64_t _factorIndice)
|
||||||
|
{
|
||||||
|
from = _from;
|
||||||
|
to = _to;
|
||||||
|
factorIndice = _factorIndice;
|
||||||
|
}
|
||||||
|
int from;
|
||||||
|
int to;
|
||||||
|
std::uint64_t factorIndice;
|
||||||
|
};
|
||||||
|
|
||||||
|
std::vector<ConstraintToFactor> lastAddedConstraints_;
|
||||||
|
int lastSwitchId_;
|
||||||
|
std::set<int> addedPoses_;
|
||||||
|
std::pair<int, std::uint64_t> lastRootFactorIndex_;
|
||||||
};
|
};
|
||||||
|
|
||||||
} /* namespace rtabmap */
|
} /* namespace rtabmap */
|
||||||
|
|||||||
@@ -33,6 +33,7 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|||||||
#include <opencv2/core/core.hpp>
|
#include <opencv2/core/core.hpp>
|
||||||
#include <rtabmap/core/Transform.h>
|
#include <rtabmap/core/Transform.h>
|
||||||
#include <rtabmap/core/Parameters.h>
|
#include <rtabmap/core/Parameters.h>
|
||||||
|
#include <rtabmap/core/CameraModel.h>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
namespace rtabmap
|
namespace rtabmap
|
||||||
@@ -163,6 +164,28 @@ void RTABMAP_CORE_EXPORT NMS(
|
|||||||
cv::Mat & descriptorsOut,
|
cv::Mat & descriptorsOut,
|
||||||
int border, int dist_thresh, int img_width, int img_height);
|
int border, int dist_thresh, int img_width, int img_height);
|
||||||
|
|
||||||
|
std::vector<int> RTABMAP_CORE_EXPORT SSC(
|
||||||
|
const std::vector<cv::KeyPoint> & keypoints, int maxKeypoints, float tolerance, int cols, int rows);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Rotate images and camera model so that the top of the image is up.
|
||||||
|
*
|
||||||
|
* The roll value of local transform of the camera model is used to estimate
|
||||||
|
* if the images have to be rotated. If there is a pitch value higher than
|
||||||
|
* 45 deg, the original images and camera model will be returned (no rotation will happen).
|
||||||
|
* The return local transform of the camera model is updated accordingly. The distortion
|
||||||
|
* model is ignored and won't be transfered to modified camera model, so this function
|
||||||
|
* expects already rectified images.
|
||||||
|
*
|
||||||
|
* @param model a valid camera model
|
||||||
|
* @param rgb a rgb/grayscale image (set cv::Mat() if not used)
|
||||||
|
* @param depth a depth image (set cv::Mat() if not used)
|
||||||
|
*/
|
||||||
|
void RTABMAP_CORE_EXPORT rotateImagesUpsideUpIfNecessary(
|
||||||
|
CameraModel & model,
|
||||||
|
cv::Mat & rgb,
|
||||||
|
cv::Mat & depth);
|
||||||
|
|
||||||
} // namespace util3d
|
} // namespace util3d
|
||||||
} // namespace rtabmap
|
} // namespace rtabmap
|
||||||
|
|
||||||
|
|||||||
@@ -455,6 +455,19 @@ RTABMAP_DEPRECATED pcl::PointCloud<pcl::PointXYZ>::Ptr RTABMAP_CORE_EXPORT loadC
|
|||||||
int downsampleStep = 1,
|
int downsampleStep = 1,
|
||||||
float voxelSize = 0.0f);
|
float voxelSize = 0.0f);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Lidar deskewing
|
||||||
|
* @param input lidar, format should have time channel
|
||||||
|
* @param input stamp of the lidar
|
||||||
|
* @param velocity in base frame
|
||||||
|
* @param velocity stamp at which it has been computed
|
||||||
|
* @return lidar deskewed
|
||||||
|
*/
|
||||||
|
LaserScan RTABMAP_CORE_EXPORT deskew(
|
||||||
|
const LaserScan & input,
|
||||||
|
double inputStamp,
|
||||||
|
const rtabmap::Transform & velocity);
|
||||||
|
|
||||||
} // namespace util3d
|
} // namespace util3d
|
||||||
} // namespace rtabmap
|
} // namespace rtabmap
|
||||||
|
|
||||||
|
|||||||
@@ -54,7 +54,8 @@ Transform RTABMAP_CORE_EXPORT estimateMotion3DTo2D(
|
|||||||
const std::map<int, cv::Point3f> & words3B = std::map<int, cv::Point3f>(),
|
const std::map<int, cv::Point3f> & words3B = std::map<int, cv::Point3f>(),
|
||||||
cv::Mat * covariance = 0, // mean reproj error if words3B is not set
|
cv::Mat * covariance = 0, // mean reproj error if words3B is not set
|
||||||
std::vector<int> * matchesOut = 0,
|
std::vector<int> * matchesOut = 0,
|
||||||
std::vector<int> * inliersOut = 0);
|
std::vector<int> * inliersOut = 0,
|
||||||
|
bool splitLinearCovarianceComponents = false);
|
||||||
|
|
||||||
Transform RTABMAP_CORE_EXPORT estimateMotion3DTo2D(
|
Transform RTABMAP_CORE_EXPORT estimateMotion3DTo2D(
|
||||||
const std::map<int, cv::Point3f> & words3A,
|
const std::map<int, cv::Point3f> & words3A,
|
||||||
@@ -72,7 +73,8 @@ Transform RTABMAP_CORE_EXPORT estimateMotion3DTo2D(
|
|||||||
const std::map<int, cv::Point3f> & words3B = std::map<int, cv::Point3f>(),
|
const std::map<int, cv::Point3f> & words3B = std::map<int, cv::Point3f>(),
|
||||||
cv::Mat * covariance = 0, // mean reproj error if words3B is not set
|
cv::Mat * covariance = 0, // mean reproj error if words3B is not set
|
||||||
std::vector<int> * matchesOut = 0,
|
std::vector<int> * matchesOut = 0,
|
||||||
std::vector<int> * inliersOut = 0);
|
std::vector<int> * inliersOut = 0,
|
||||||
|
bool splitLinearCovarianceComponents = false);
|
||||||
|
|
||||||
Transform RTABMAP_CORE_EXPORT estimateMotion3DTo3D(
|
Transform RTABMAP_CORE_EXPORT estimateMotion3DTo3D(
|
||||||
const std::map<int, cv::Point3f> & words3A,
|
const std::map<int, cv::Point3f> & words3A,
|
||||||
|
|||||||
@@ -13,8 +13,10 @@ SET(SRC_FILES
|
|||||||
|
|
||||||
Recovery.cpp
|
Recovery.cpp
|
||||||
|
|
||||||
|
SensorCapture.cpp
|
||||||
|
SensorCaptureThread.cpp
|
||||||
|
|
||||||
Camera.cpp
|
Camera.cpp
|
||||||
CameraThread.cpp
|
|
||||||
CameraModel.cpp
|
CameraModel.cpp
|
||||||
|
|
||||||
camera/CameraFreenect.cpp
|
camera/CameraFreenect.cpp
|
||||||
@@ -38,6 +40,7 @@ SET(SRC_FILES
|
|||||||
camera/CameraVideo.cpp
|
camera/CameraVideo.cpp
|
||||||
camera/CameraMyntEye.cpp
|
camera/CameraMyntEye.cpp
|
||||||
camera/CameraDepthAI.cpp
|
camera/CameraDepthAI.cpp
|
||||||
|
camera/CameraSeerSense.cpp
|
||||||
|
|
||||||
EpipolarGeometry.cpp
|
EpipolarGeometry.cpp
|
||||||
VisualWord.cpp
|
VisualWord.cpp
|
||||||
@@ -115,6 +118,8 @@ SET(SRC_FILES
|
|||||||
|
|
||||||
MarkerDetector.cpp
|
MarkerDetector.cpp
|
||||||
|
|
||||||
|
GlobalDescriptorExtractor.cpp
|
||||||
|
|
||||||
GainCompensator.cpp
|
GainCompensator.cpp
|
||||||
|
|
||||||
rtflann/ext/lz4.c
|
rtflann/ext/lz4.c
|
||||||
@@ -132,6 +137,13 @@ SET(SRC_FILES
|
|||||||
opencv/five-point.cpp
|
opencv/five-point.cpp
|
||||||
)
|
)
|
||||||
|
|
||||||
|
IF(PCL_VERSION VERSION_GREATER_EQUAL "1.8")
|
||||||
|
SET(SRC_FILES
|
||||||
|
${SRC_FILES}
|
||||||
|
lidar/LidarVLP16.cpp
|
||||||
|
)
|
||||||
|
ENDIF(PCL_VERSION VERSION_GREATER_EQUAL "1.8")
|
||||||
|
|
||||||
IF(OpenCV_VERSION_MAJOR EQUAL 2)
|
IF(OpenCV_VERSION_MAJOR EQUAL 2)
|
||||||
SET(SRC_FILES
|
SET(SRC_FILES
|
||||||
${SRC_FILES}
|
${SRC_FILES}
|
||||||
@@ -173,14 +185,14 @@ SET(PUBLIC_LIBRARIES
|
|||||||
${PCL_LIBRARIES}
|
${PCL_LIBRARIES}
|
||||||
)
|
)
|
||||||
|
|
||||||
IF(Sqlite3_FOUND)
|
IF(SQLite3_FOUND)
|
||||||
SET(INCLUDE_DIRS
|
SET(INCLUDE_DIRS
|
||||||
${INCLUDE_DIRS}
|
${INCLUDE_DIRS}
|
||||||
${Sqlite3_INCLUDE_DIRS}
|
${SQLite3_INCLUDE_DIRS}
|
||||||
)
|
)
|
||||||
SET(LIBRARIES
|
SET(LIBRARIES
|
||||||
${LIBRARIES}
|
${LIBRARIES}
|
||||||
${Sqlite3_LIBRARIES}
|
${SQLite3_LIBRARIES}
|
||||||
)
|
)
|
||||||
ELSE()
|
ELSE()
|
||||||
SET(SRC_FILES
|
SET(SRC_FILES
|
||||||
@@ -224,6 +236,7 @@ IF(WITH_PYTHON AND Python3_FOUND)
|
|||||||
python/PythonInterface.cpp
|
python/PythonInterface.cpp
|
||||||
python/PyMatcher.cpp
|
python/PyMatcher.cpp
|
||||||
python/PyDetector.cpp
|
python/PyDetector.cpp
|
||||||
|
python/PyDescriptor.cpp
|
||||||
)
|
)
|
||||||
SET(INCLUDE_DIRS
|
SET(INCLUDE_DIRS
|
||||||
${TORCH_INCLUDE_DIRS}
|
${TORCH_INCLUDE_DIRS}
|
||||||
@@ -371,6 +384,13 @@ IF(depthai_FOUND)
|
|||||||
)
|
)
|
||||||
ENDIF(depthai_FOUND)
|
ENDIF(depthai_FOUND)
|
||||||
|
|
||||||
|
IF(xvsdk_FOUND)
|
||||||
|
SET(PUBLIC_LIBRARIES
|
||||||
|
${PUBLIC_LIBRARIES}
|
||||||
|
${xvsdk_LIBRARIES}
|
||||||
|
)
|
||||||
|
ENDIF(xvsdk_FOUND)
|
||||||
|
|
||||||
IF(TARGET OpenMP::OpenMP_CXX)
|
IF(TARGET OpenMP::OpenMP_CXX)
|
||||||
SET(LIBRARIES
|
SET(LIBRARIES
|
||||||
${LIBRARIES}
|
${LIBRARIES}
|
||||||
|
|||||||
@@ -26,42 +26,25 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#include "rtabmap/core/Camera.h"
|
#include "rtabmap/core/Camera.h"
|
||||||
|
#include "rtabmap/core/IMUFilter.h"
|
||||||
|
|
||||||
#include <rtabmap/utilite/UEventsManager.h>
|
|
||||||
#include <rtabmap/utilite/UConversion.h>
|
|
||||||
#include <rtabmap/utilite/UStl.h>
|
#include <rtabmap/utilite/UStl.h>
|
||||||
#include <rtabmap/utilite/UConversion.h>
|
|
||||||
#include <rtabmap/utilite/UFile.h>
|
#include <rtabmap/utilite/UFile.h>
|
||||||
#include <rtabmap/utilite/UDirectory.h>
|
#include <rtabmap/utilite/UDirectory.h>
|
||||||
#include <rtabmap/utilite/UTimer.h>
|
#include <rtabmap/utilite/UEventsManager.h>
|
||||||
|
|
||||||
#include <opencv2/imgproc/imgproc.hpp>
|
|
||||||
|
|
||||||
#include <iostream>
|
|
||||||
#include <cmath>
|
|
||||||
|
|
||||||
namespace rtabmap
|
namespace rtabmap
|
||||||
{
|
{
|
||||||
|
|
||||||
Camera::Camera(float imageRate, const Transform & localTransform) :
|
Camera::Camera(float imageRate, const Transform & localTransform) :
|
||||||
_imageRate(imageRate),
|
SensorCapture(imageRate, localTransform*CameraModel::opticalRotation()),
|
||||||
_localTransform(localTransform*CameraModel::opticalRotation()),
|
imuFilter_(0),
|
||||||
_targetImageSize(0,0),
|
publishInterIMU_(false)
|
||||||
_frameRateTimer(new UTimer()),
|
{}
|
||||||
_seq(0)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
Camera::~Camera()
|
Camera::~Camera()
|
||||||
{
|
{
|
||||||
UDEBUG("");
|
delete imuFilter_;
|
||||||
delete _frameRateTimer;
|
|
||||||
UDEBUG("");
|
|
||||||
}
|
|
||||||
|
|
||||||
void Camera::resetTimer()
|
|
||||||
{
|
|
||||||
_frameRateTimer->start();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Camera::initFromFile(const std::string & calibrationPath)
|
bool Camera::initFromFile(const std::string & calibrationPath)
|
||||||
@@ -69,54 +52,32 @@ bool Camera::initFromFile(const std::string & calibrationPath)
|
|||||||
return init(UDirectory::getDir(calibrationPath), uSplit(UFile::getName(calibrationPath), '.').front());
|
return init(UDirectory::getDir(calibrationPath), uSplit(UFile::getName(calibrationPath), '.').front());
|
||||||
}
|
}
|
||||||
|
|
||||||
SensorData Camera::takeImage(CameraInfo * info)
|
void Camera::setInterIMUPublishing(bool enabled, IMUFilter * filter)
|
||||||
{
|
{
|
||||||
bool warnFrameRateTooHigh = false;
|
publishInterIMU_ = enabled;
|
||||||
float actualFrameRate = 0;
|
delete imuFilter_;
|
||||||
float imageRate = _imageRate;
|
imuFilter_ = filter;
|
||||||
if(imageRate>0)
|
}
|
||||||
{
|
|
||||||
int sleepTime = (1000.0f/imageRate - 1000.0f*_frameRateTimer->getElapsedTime());
|
|
||||||
if(sleepTime > 2)
|
|
||||||
{
|
|
||||||
uSleep(sleepTime-2);
|
|
||||||
}
|
|
||||||
else if(sleepTime < 0)
|
|
||||||
{
|
|
||||||
warnFrameRateTooHigh = true;
|
|
||||||
actualFrameRate = 1.0/(_frameRateTimer->getElapsedTime());
|
|
||||||
}
|
|
||||||
|
|
||||||
// Add precision at the cost of a small overhead
|
void Camera::postInterIMU(const IMU & imu, double stamp)
|
||||||
while(_frameRateTimer->getElapsedTime() < 1.0/double(imageRate)-0.000001)
|
{
|
||||||
{
|
if(imuFilter_)
|
||||||
//
|
|
||||||
}
|
|
||||||
|
|
||||||
double slept = _frameRateTimer->getElapsedTime();
|
|
||||||
_frameRateTimer->start();
|
|
||||||
UDEBUG("slept=%fs vs target=%fs", slept, 1.0/double(imageRate));
|
|
||||||
}
|
|
||||||
|
|
||||||
UTimer timer;
|
|
||||||
SensorData data = this->captureImage(info);
|
|
||||||
double captureTime = timer.ticks();
|
|
||||||
if(warnFrameRateTooHigh)
|
|
||||||
{
|
{
|
||||||
UWARN("Camera: Cannot reach target image rate %f Hz, current rate is %f Hz and capture time = %f s.",
|
imuFilter_->update(
|
||||||
imageRate, actualFrameRate, captureTime);
|
imu.angularVelocity()[0], imu.angularVelocity()[1], imu.angularVelocity()[2],
|
||||||
|
imu.linearAcceleration()[0], imu.linearAcceleration()[1], imu.linearAcceleration()[2],
|
||||||
|
stamp);
|
||||||
|
cv::Vec4d q;
|
||||||
|
imuFilter_->getOrientation(q[0],q[1],q[2],q[3]);
|
||||||
|
UEventsManager::post(new IMUEvent(IMU(
|
||||||
|
q, cv::Mat(),
|
||||||
|
imu.angularVelocity(), imu.angularVelocityCovariance(),
|
||||||
|
imu.linearAcceleration(), imu.linearAccelerationCovariance(),
|
||||||
|
imu.localTransform()),
|
||||||
|
stamp));
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
else
|
UEventsManager::post(new IMUEvent(imu, stamp));
|
||||||
{
|
|
||||||
UDEBUG("Time capturing image = %fs", captureTime);
|
|
||||||
}
|
|
||||||
if(info)
|
|
||||||
{
|
|
||||||
info->id = data.id();
|
|
||||||
info->stamp = data.stamp();
|
|
||||||
info->timeCapture = captureTime;
|
|
||||||
}
|
|
||||||
return data;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace rtabmap
|
} // namespace rtabmap
|
||||||
|
|||||||
@@ -60,7 +60,7 @@ CameraModel::CameraModel(
|
|||||||
localTransform_(localTransform)
|
localTransform_(localTransform)
|
||||||
{
|
{
|
||||||
UASSERT(K_.empty() || (K_.rows == 3 && K_.cols == 3 && K_.type() == CV_64FC1));
|
UASSERT(K_.empty() || (K_.rows == 3 && K_.cols == 3 && K_.type() == CV_64FC1));
|
||||||
UASSERT(D_.empty() || (D_.rows == 1 && (D_.cols == 4 || D_.cols == 5 || D_.cols == 6 || D_.cols == 8) && D_.type() == CV_64FC1));
|
UASSERT(D_.empty() || (D_.rows == 1 && (D_.cols == 4 || D_.cols == 5 || D_.cols == 6 || D_.cols == 8 || D_.cols == 12 || D_.cols == 14) && D_.type() == CV_64FC1));
|
||||||
UASSERT(R_.empty() || (R_.rows == 3 && R_.cols == 3 && R_.type() == CV_64FC1));
|
UASSERT(R_.empty() || (R_.rows == 3 && R_.cols == 3 && R_.type() == CV_64FC1));
|
||||||
UASSERT(P_.empty() || (P_.rows == 3 && P_.cols == 4 && P_.type() == CV_64FC1));
|
UASSERT(P_.empty() || (P_.rows == 3 && P_.cols == 4 && P_.type() == CV_64FC1));
|
||||||
}
|
}
|
||||||
@@ -156,7 +156,7 @@ CameraModel::CameraModel(
|
|||||||
bool CameraModel::initRectificationMap()
|
bool CameraModel::initRectificationMap()
|
||||||
{
|
{
|
||||||
UASSERT(imageSize_.height > 0 && imageSize_.width > 0);
|
UASSERT(imageSize_.height > 0 && imageSize_.width > 0);
|
||||||
UASSERT(D_.rows == 1 && (D_.cols == 4 || D_.cols == 5 || D_.cols == 6 || D_.cols == 8));
|
UASSERT(D_.rows == 1 && (D_.cols == 4 || D_.cols == 5 || D_.cols == 6 || D_.cols == 8 || D_.cols == 12 || D_.cols == 14));
|
||||||
UASSERT(R_.rows == 3 && R_.cols == 3);
|
UASSERT(R_.rows == 3 && R_.cols == 3);
|
||||||
UASSERT(P_.rows == 3 && P_.cols == 4);
|
UASSERT(P_.rows == 3 && P_.cols == 4);
|
||||||
// init rectification map
|
// init rectification map
|
||||||
@@ -279,7 +279,7 @@ bool CameraModel::load(const std::string & filePath)
|
|||||||
std::vector<double> data;
|
std::vector<double> data;
|
||||||
n["data"] >> data;
|
n["data"] >> data;
|
||||||
UASSERT(rows*cols == (int)data.size());
|
UASSERT(rows*cols == (int)data.size());
|
||||||
UASSERT(rows == 1 && (cols == 4 || cols == 5 || cols == 8));
|
UASSERT(rows == 1 && (cols == 4 || cols == 5 || cols == 8 || cols == 12 || cols == 14));
|
||||||
D_ = cv::Mat(rows, cols, CV_64FC1, data.data()).clone();
|
D_ = cv::Mat(rows, cols, CV_64FC1, data.data()).clone();
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
|||||||
@@ -6728,7 +6728,7 @@ void DBDriverSqlite3::stepGlobalDescriptor(sqlite3_stmt * ppStmt,
|
|||||||
|
|
||||||
//data
|
//data
|
||||||
std::vector<unsigned char> dataBytes = rtabmap::compressData(descriptor.data());
|
std::vector<unsigned char> dataBytes = rtabmap::compressData(descriptor.data());
|
||||||
if(infoBytes.empty())
|
if(dataBytes.empty())
|
||||||
{
|
{
|
||||||
rc = sqlite3_bind_null(ppStmt, index++);
|
rc = sqlite3_bind_null(ppStmt, index++);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -25,6 +25,7 @@ ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
|||||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#include <rtabmap/core/SensorEvent.h>
|
||||||
#include "rtabmap/core/DBReader.h"
|
#include "rtabmap/core/DBReader.h"
|
||||||
#include "rtabmap/core/DBDriver.h"
|
#include "rtabmap/core/DBDriver.h"
|
||||||
|
|
||||||
@@ -34,7 +35,6 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|||||||
#include <rtabmap/utilite/UConversion.h>
|
#include <rtabmap/utilite/UConversion.h>
|
||||||
#include <rtabmap/utilite/UEventsManager.h>
|
#include <rtabmap/utilite/UEventsManager.h>
|
||||||
|
|
||||||
#include "rtabmap/core/CameraEvent.h"
|
|
||||||
#include "rtabmap/core/RtabmapEvent.h"
|
#include "rtabmap/core/RtabmapEvent.h"
|
||||||
#include "rtabmap/core/OdometryEvent.h"
|
#include "rtabmap/core/OdometryEvent.h"
|
||||||
#include "rtabmap/core/util3d.h"
|
#include "rtabmap/core/util3d.h"
|
||||||
@@ -268,7 +268,13 @@ std::string DBReader::getSerial() const
|
|||||||
return "DBReader";
|
return "DBReader";
|
||||||
}
|
}
|
||||||
|
|
||||||
SensorData DBReader::captureImage(CameraInfo * info)
|
bool DBReader::getPose(double stamp, Transform & pose, cv::Mat & covariance, double maxWaitTime)
|
||||||
|
{
|
||||||
|
UERROR("DBReader only provides pose when capturing data, it cannot provide asynchronous pose.");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
SensorData DBReader::captureImage(SensorCaptureInfo * info)
|
||||||
{
|
{
|
||||||
SensorData data = this->getNextData(info);
|
SensorData data = this->getNextData(info);
|
||||||
if(data.id()>0 && _stopId>0 && data.id() > _stopId)
|
if(data.id()>0 && _stopId>0 && data.id() > _stopId)
|
||||||
@@ -370,7 +376,7 @@ SensorData DBReader::captureImage(CameraInfo * info)
|
|||||||
return data;
|
return data;
|
||||||
}
|
}
|
||||||
|
|
||||||
SensorData DBReader::getNextData(CameraInfo * info)
|
SensorData DBReader::getNextData(SensorCaptureInfo * info)
|
||||||
{
|
{
|
||||||
SensorData data;
|
SensorData data;
|
||||||
if(_dbDriver)
|
if(_dbDriver)
|
||||||
|
|||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user