Added CameraStereoZedOC (Zed Open Capture driver).

* Added CameraStereoZedOC (Zed Open Capture driver). Calibration: added stereo baseline option, show warning if fx is very different after stereo calibration.

* Fixed build without Zed Open Capture. Fixed "any" prefix added to all tools when WITH_ZEDOC=ON. UI: fixed Zed Open Capture action not disabled when not built with it.
This commit is contained in:
matlabbe
2021-02-28 10:31:18 -05:00
committed by GitHub
parent 862eb0a90a
commit 967c57d165
21 changed files with 1495 additions and 87 deletions

View File

@@ -183,6 +183,7 @@ option(WITH_POINTMATCHER "Include libpointmatcher support" ON)
option(WITH_LOAM "Include LOAM support" ON)
option(WITH_FLYCAPTURE2 "Include FlyCapture2/Triclops support" ON)
option(WITH_ZED "Include ZED sdk support" ON)
option(WITH_ZEDOC "Include ZED Open Capture support" ON)
option(WITH_REALSENSE "Include RealSense support" ON)
option(WITH_REALSENSE_SLAM "Include RealSenseSlam support" ON)
option(WITH_REALSENSE2 "Include RealSense support" ON)
@@ -474,6 +475,20 @@ IF(WITH_ZED)
ENDIF(ZED_FOUND)
ENDIF(WITH_ZED)
IF(WITH_ZEDOC)
find_package(ZEDOC QUIET)
IF(ZEDOC_FOUND)
MESSAGE(STATUS "Found ZED Open Capture: ${ZEDOC_INCLUDE_DIRS}")
## look for HIDAPI
find_package(HIDAPI)
IF(HIDAPI_FOUND)
MESSAGE(STATUS "Found HIDAPI: ${HIDAPI_INCLUDE_DIRS}")
ELSE()
MESSAGE(FATAL_ERROR "HIDAPI is required to build with Zed Open Capture! Set -DWITH_ZEDOC=OFF if you don't have HIDAPI.")
ENDIF()
ENDIF(ZEDOC_FOUND)
ENDIF(WITH_ZEDOC)
IF(WITH_REALSENSE)
IF(WITH_REALSENSE_SLAM)
FIND_PACKAGE(RealSense QUIET COMPONENTS slam)
@@ -638,6 +653,7 @@ IF(NOT MSVC)
GTSAM_FOUND OR
CERES_FOUND OR
ZED_FOUND OR
ZEDOC_FOUND OR
ANDROID OR
RealSense_FOUND OR
realsense2_FOUND OR
@@ -791,6 +807,11 @@ IF(NOT ZED_FOUND)
ELSE()
SET(CONF_DEPENDENCIES ${CONF_DEPENDENCIES} ${ZED_LIBRARIES} ${CUDA_LIBRARIES})
ENDIF()
IF(NOT ZEDOC_FOUND)
SET(ZEDOC "//")
ELSE()
SET(CONF_DEPENDENCIES ${CONF_DEPENDENCIES} ${ZEDOC_LIBRARIES})
ENDIF()
IF(NOT RealSense_FOUND)
SET(REALSENSE "//")
ELSE()
@@ -1324,6 +1345,14 @@ ELSE()
MESSAGE(STATUS " With ZED = NO (ZED sdk and/or cuda not found)")
ENDIF()
IF(ZEDOC_FOUND)
MESSAGE(STATUS " With ZEDOC = YES")
ELSEIF(NOT WITH_ZEDOC)
MESSAGE(STATUS " With ZEDOC = NO (WITH_ZEDOC=OFF)")
ELSE()
MESSAGE(STATUS " With ZEDOC = NO (ZED Open Capture not found)")
ENDIF()
IF(RealSense_FOUND)
MESSAGE(STATUS " With RealSense = YES (License: Apache-2)")
IF(RealSenseSlam_FOUND)

View File

@@ -57,6 +57,7 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
@DC1394@#define RTABMAP_DC1394
@FLYCAPTURE2@#define RTABMAP_FLYCAPTURE2
@ZED@#define RTABMAP_ZED
@ZEDOC@#define RTABMAP_ZEDOC
@REALSENSE@#define RTABMAP_REALSENSE
@REALSENSESLAM@#define RTABMAP_REALSENSE_SLAM
@REALSENSE2@#define RTABMAP_REALSENSE2

View File

@@ -0,0 +1,234 @@
#.rst:
# FindHIDAPI
# ----------
#
# Try to find HIDAPI library, from http://www.signal11.us/oss/hidapi/
#
# Cache Variables: (probably not for direct use in your scripts)
# HIDAPI_INCLUDE_DIR
# HIDAPI_LIBRARY
#
# Non-cache variables you might use in your CMakeLists.txt:
# HIDAPI_FOUND
# HIDAPI_INCLUDE_DIRS
# HIDAPI_LIBRARIES
#
# COMPONENTS
# ^^^^^^^^^^
#
# This module respects several COMPONENTS specifying the backend you prefer:
# ``any`` (the default), ``libusb``, and ``hidraw``.
# The availablility of the latter two depends on your platform.
#
#
# IMPORTED Targets
# ^^^^^^^^^^^^^^^^
# This module defines :prop_tgt:`IMPORTED` target ``HIDAPI::hidapi`` (in all cases or
# if no components specified), ``HIDAPI::hidapi-libusb`` (if you requested the libusb component),
# and ``HIDAPI::hidapi-hidraw`` (if you requested the hidraw component),
#
# Result Variables
# ^^^^^^^^^^^^^^^^
#
# ``HIDAPI_FOUND``
# True if HIDAPI or the requested components (if any) were found.
#
# We recommend using the imported targets instead of the following.
#
# ``HIDAPI_INCLUDE_DIRS``
# ``HIDAPI_LIBRARIES``
#
# Original Author:
# 2009-2010, 2019 Ryan Pavlik <ryan.pavlik@collabora.com> <abiryan@ryand.net>
# http://academic.cleardefinition.com
#
# Copyright Iowa State University 2009-2010.
# Copyright Collabora, Ltd. 2019.
# Distributed under the Boost Software License, Version 1.0.
# (See accompanying file LICENSE_1_0.txt or copy at
# http://www.boost.org/LICENSE_1_0.txt)
cmake_policy(SET CMP0045 NEW)
cmake_policy(SET CMP0053 NEW)
cmake_policy(SET CMP0054 NEW)
set(HIDAPI_ROOT_DIR
"${HIDAPI_ROOT_DIR}"
CACHE PATH "Root to search for HIDAPI")
# Clean up components
if("${HIDAPI_FIND_COMPONENTS}")
if(WIN32 OR APPLE)
# This makes no sense on Windows or Mac, which have native APIs
list(REMOVE HIDAPI_FIND_COMPONENTS libusb)
endif()
if(NOT ${CMAKE_SYSTEM} MATCHES "Linux")
# hidraw is only on linux
list(REMOVE HIDAPI_FIND_COMPONENTS hidraw)
endif()
endif()
if(NOT "${HIDAPI_FIND_COMPONENTS}")
# Default to any
set(HIDAPI_FIND_COMPONENTS any)
endif()
# Ask pkg-config for hints
find_package(PkgConfig QUIET)
if(PKG_CONFIG_FOUND)
set(_old_prefix_path "${CMAKE_PREFIX_PATH}")
# So pkg-config uses HIDAPI_ROOT_DIR too.
if(HIDAPI_ROOT_DIR)
list(APPEND CMAKE_PREFIX_PATH ${HIDAPI_ROOT_DIR})
endif()
pkg_check_modules(PC_HIDAPI_LIBUSB QUIET hidapi-libusb)
pkg_check_modules(PC_HIDAPI_HIDRAW QUIET hidapi-hidraw)
# Restore
set(CMAKE_PREFIX_PATH "${_old_prefix_path}")
endif()
# Actually search
find_library(
HIDAPI_UNDECORATED_LIBRARY
NAMES hidapi
PATHS "${HIDAPI_ROOT_DIR}"
PATH_SUFFIXES lib)
find_library(
HIDAPI_LIBUSB_LIBRARY
NAMES hidapi hidapi-libusb
PATHS "${HIDAPI_ROOT_DIR}"
PATH_SUFFIXES lib
HINTS ${PC_HIDAPI_LIBUSB_LIBRARY_DIRS})
if(CMAKE_SYSTEM MATCHES "Linux")
find_library(
HIDAPI_HIDRAW_LIBRARY
NAMES hidapi-hidraw
HINTS ${PC_HIDAPI_HIDRAW_LIBRARY_DIRS})
endif()
find_path(
HIDAPI_INCLUDE_DIR
NAMES hidapi.h
PATHS "${HIDAPI_ROOT_DIR}"
PATH_SUFFIXES hidapi include include/hidapi
HINTS ${PC_HIDAPI_HIDRAW_INCLUDE_DIRS} ${PC_HIDAPI_LIBUSB_INCLUDE_DIRS})
find_package(Threads QUIET)
###
# Compute the "I don't care which backend" library
###
set(HIDAPI_LIBRARY)
# First, try to use a preferred backend if supplied
if("${HIDAPI_FIND_COMPONENTS}" MATCHES "libusb"
AND HIDAPI_LIBUSB_LIBRARY
AND NOT HIDAPI_LIBRARY)
set(HIDAPI_LIBRARY ${HIDAPI_LIBUSB_LIBRARY})
endif()
if("${HIDAPI_FIND_COMPONENTS}" MATCHES "hidraw"
AND HIDAPI_HIDRAW_LIBRARY
AND NOT HIDAPI_LIBRARY)
set(HIDAPI_LIBRARY ${HIDAPI_HIDRAW_LIBRARY})
endif()
# Then, if we don't have a preferred one, settle for anything.
if(NOT HIDAPI_LIBRARY)
if(HIDAPI_LIBUSB_LIBRARY)
set(HIDAPI_LIBRARY ${HIDAPI_LIBUSB_LIBRARY})
elseif(HIDAPI_HIDRAW_LIBRARY)
set(HIDAPI_LIBRARY ${HIDAPI_HIDRAW_LIBRARY})
elseif(HIDAPI_UNDECORATED_LIBRARY)
set(HIDAPI_LIBRARY ${HIDAPI_UNDECORATED_LIBRARY})
endif()
endif()
###
# Determine if the various requested components are found.
###
set(_hidapi_component_required_vars)
foreach(_comp IN LISTS HIDAPI_FIND_COMPONENTS)
if("${_comp}" STREQUAL "any")
list(APPEND _hidapi_component_required_vars HIDAPI_INCLUDE_DIR
HIDAPI_LIBRARY)
if(HIDAPI_INCLUDE_DIR AND EXISTS "${HIDAPI_LIBRARY}")
set(HIDAPI_any_FOUND TRUE)
mark_as_advanced(HIDAPI_INCLUDE_DIR)
else()
set(HIDAPI_any_FOUND FALSE)
endif()
elseif("${_comp}" STREQUAL "libusb")
list(APPEND _hidapi_component_required_vars HIDAPI_INCLUDE_DIR
HIDAPI_LIBUSB_LIBRARY)
if(HIDAPI_INCLUDE_DIR AND EXISTS "${HIDAPI_LIBUSB_LIBRARY}")
set(HIDAPI_libusb_FOUND TRUE)
mark_as_advanced(HIDAPI_INCLUDE_DIR HIDAPI_LIBUSB_LIBRARY)
else()
set(HIDAPI_libusb_FOUND FALSE)
endif()
elseif("${_comp}" STREQUAL "hidraw")
list(APPEND _hidapi_component_required_vars HIDAPI_INCLUDE_DIR
HIDAPI_HIDRAW_LIBRARY)
if(HIDAPI_INCLUDE_DIR AND EXISTS "${HIDAPI_HIDRAW_LIBRARY}")
set(HIDAPI_hidraw_FOUND TRUE)
mark_as_advanced(HIDAPI_INCLUDE_DIR HIDAPI_HIDRAW_LIBRARY)
else()
set(HIDAPI_hidraw_FOUND FALSE)
endif()
else()
message(WARNING "${_comp} is not a recognized HIDAPI component")
set(HIDAPI_${_comp}_FOUND FALSE)
endif()
endforeach()
unset(_comp)
###
# FPHSA call
###
include(FindPackageHandleStandardArgs)
find_package_handle_standard_args(
HIDAPI REQUIRED_VARS ${_hidapi_component_required_vars} THREADS_FOUND
HANDLE_COMPONENTS)
if(HIDAPI_FOUND)
set(HIDAPI_LIBRARIES "${HIDAPI_LIBRARY}")
set(HIDAPI_INCLUDE_DIRS "${HIDAPI_INCLUDE_DIR}")
if(NOT TARGET HIDAPI::hidapi)
add_library(HIDAPI::hidapi UNKNOWN IMPORTED)
set_target_properties(
HIDAPI::hidapi
PROPERTIES
IMPORTED_LINK_INTERFACE_LANGUAGES "C"
IMPORTED_LOCATION ${HIDAPI_LIBRARY})
set_property(
TARGET HIDAPI::hidapi PROPERTY IMPORTED_LINK_INTERFACE_LIBRARIES
Threads::Threads)
endif()
endif()
if(HIDAPI_libusb_FOUND AND NOT TARGET HIDAPI::hidapi-libusb)
add_library(HIDAPI::hidapi-libusb UNKNOWN IMPORTED)
set_target_properties(
HIDAPI::hidapi-libusb
PROPERTIES IMPORTED_LINK_INTERFACE_LANGUAGES "C" IMPORTED_LOCATION
${HIDAPI_LIBUSB_LIBRARY})
set_property(TARGET HIDAPI::hidapi-libusb
PROPERTY IMPORTED_LINK_INTERFACE_LIBRARIES Threads::Threads)
endif()
if(HIDAPI_hidraw_FOUND AND NOT TARGET HIDAPI::hidapi-hidraw)
add_library(HIDAPI::hidapi-hidraw UNKNOWN IMPORTED)
set_target_properties(
HIDAPI::hidapi-hidraw
PROPERTIES IMPORTED_LINK_INTERFACE_LANGUAGES "C" IMPORTED_LOCATION
${HIDAPI_HIDRAW_LIBRARY})
set_property(TARGET HIDAPI::hidapi-hidraw
PROPERTY IMPORTED_LINK_INTERFACE_LIBRARIES Threads::Threads)
endif()

View File

@@ -0,0 +1,28 @@
# - Find ZED Open Capture
# This module finds zed open capture library
#
# It sets the following variables:
# ZEDOC_FOUND - Set to false, or undefined, if ZEDOC isn't found.
# ZEDOC_INCLUDE_DIRS - The ZEDOC include directory.
# ZEDOC_LIBRARIES - The ZEDOC library to link against.
find_library(ZEDOC_LIBRARY NAMES zed_open_capture PATHS $ENV{ZEDOC_ROOT_DIR}/lib)
find_path(ZEDOC_INCLUDE_DIR NAMES zed-open-capture/videocapture.hpp PATHS $ENV{ZEDOC_ROOT_DIR}/include)
IF (ZEDOC_INCLUDE_DIR AND ZEDOC_LIBRARY)
SET(ZEDOC_FOUND TRUE)
SET(ZEDOC_INCLUDE_DIRS ${ZEDOC_INCLUDE_DIR})
SET(ZEDOC_LIBRARIES ${ZEDOC_LIBRARY})
ENDIF (ZEDOC_INCLUDE_DIR AND ZEDOC_LIBRARY)
IF (ZEDOC_FOUND)
# show which ZEDOC was found only if not quiet
IF (NOT _FIND_QUIETLY)
MESSAGE(STATUS "Found ZEDOC: ${ZEDOC_LIBRARIES}")
ENDIF (NOT ZEDOC_FIND_QUIETLY)
ELSE (ZEDOC_FOUND)
# fatal error if ZEDOC is required but not found
IF (ZEDOC_FIND_REQUIRED)
MESSAGE(FATAL_ERROR "Could not find ZEDOC (Zed Open Capture)")
ENDIF (ZEDOC_FIND_REQUIRED)
ENDIF (ZEDOC_FOUND)

View File

@@ -32,5 +32,6 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include <rtabmap/core/camera/CameraStereoImages.h>
#include <rtabmap/core/camera/CameraStereoVideo.h>
#include <rtabmap/core/camera/CameraStereoZed.h>
#include <rtabmap/core/camera/CameraStereoZedOC.h>
#include <rtabmap/core/camera/CameraStereoTara.h>
#include <rtabmap/core/camera/CameraMyntEye.h>

View File

@@ -0,0 +1,83 @@
/*
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/RtabmapExp.h" // DLL export/import defines
#include "rtabmap/core/StereoCameraModel.h"
#include "rtabmap/core/Camera.h"
#include "rtabmap/core/Version.h"
namespace sl_oc {
namespace video {
class VideoCapture;
}
namespace sensors {
class SensorCapture;
}
}
namespace rtabmap
{
class ZedOCThread;
class RTABMAP_EXP CameraStereoZedOC :
public Camera
{
public:
static bool available();
public:
CameraStereoZedOC(
int deviceId,
int resolution = 3, // 0=HD2K, 1=HD1080, 2=HD720, 3=VGA
float imageRate=0.0f,
const Transform & localTransform = CameraModel::opticalRotation());
virtual ~CameraStereoZedOC();
virtual bool init(const std::string & calibrationFolder = ".", const std::string & cameraName = "");
virtual bool isCalibrated() const;
virtual std::string getSerial() const;
protected:
virtual SensorData captureImage(CameraInfo * info = 0);
private:
#ifdef RTABMAP_ZEDOC
sl_oc::video::VideoCapture * zed_;
sl_oc::sensors::SensorCapture * sensors_;
ZedOCThread * imuThread_;
StereoCameraModel stereoModel_;
int usbDevice_;
int resolution_;
uint64_t lastStamp_;
#endif
};
} // namespace rtabmap

View File

@@ -33,6 +33,7 @@ SET(SRC_FILES
camera/CameraStereoImages.cpp
camera/CameraStereoVideo.cpp
camera/CameraStereoZed.cpp
camera/CameraStereoZedOC.cpp
camera/CameraStereoTara.cpp
camera/CameraVideo.cpp
camera/CameraMyntEye.cpp
@@ -469,6 +470,19 @@ IF(ZED_FOUND)
ENDIF(CUDA_FOUND)
ENDIF(ZED_FOUND)
IF(ZEDOC_FOUND)
SET(INCLUDE_DIRS
${INCLUDE_DIRS}
${ZEDOC_INCLUDE_DIRS}
${HIDAPI_INCLUDE_DIRS}
)
SET(LIBRARIES
${LIBRARIES}
${ZEDOC_LIBRARIES}
${HIDAPI_LIBRARIES}
)
ENDIF(ZEDOC_FOUND)
IF(octomap_FOUND)
SET(INCLUDE_DIRS
${INCLUDE_DIRS}

View File

@@ -401,7 +401,11 @@ bool StereoCameraModel::saveStereoTransform(const std::string & directory) const
}
else
{
UERROR("Failed saving stereo extrinsics (they are null).");
UERROR("Failed saving stereo extrinsics (they are null):");
std::cout << "R= " << R_ << std::endl;
std::cout << "T= " << T_ << std::endl;
std::cout << "E= " << T_ << std::endl;
std::cout << "F= " << F_ << std::endl;
}
return false;
}

View File

@@ -0,0 +1,782 @@
/*
Copyright (c) 2010-2016, Mathieu Labbe - IntRoLab - Universite de Sherbrooke
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
* Neither the name of the Universite de Sherbrooke nor the
names of its contributors may be used to endorse or promote products
derived from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include <rtabmap/core/camera/CameraStereoZedOC.h>
#include <rtabmap/utilite/UTimer.h>
#include <rtabmap/utilite/UThread.h>
#include <rtabmap/utilite/UEventsManager.h>
#include <rtabmap/utilite/UConversion.h>
#ifdef RTABMAP_ZEDOC
#define VIDEO_MOD_AVAILABLE
#define SENSORS_MOD_AVAILABLE
#include <zed-open-capture/videocapture.hpp>
#include <zed-open-capture/sensorcapture.hpp>
#include "SimpleIni.h"
///////////////////////////////////////////////////////////////////////////
//
// Copyright (c) 2018, STEREOLABS.
//
// All rights reserved.
//
// 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
// OWNER 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.
//
///////////////////////////////////////////////////////////////////////////
inline std::vector<std::string> &split(const std::string &s, char delim, std::vector<std::string> &elems) {
std::stringstream ss(s);
std::string item;
while (getline(ss, item, delim)) {
elems.push_back(item);
}
return elems;
}
inline std::vector<std::string> split(const std::string &s, char delim) {
std::vector<std::string> elems;
split(s, delim, elems);
return elems;
}
class ConfManager {
public:
ConfManager(std::string filename) {
filename_ = filename;
ini_.SetUnicode();
SI_Error rc = ini_.LoadFile(filename_.c_str());
is_opened_ = !(rc < 0);
}
~ConfManager() {
//if (is_opened_) ini_.SaveFile(filename_.c_str());
}
float getValue(std::string key, float default_value = -1) {
if (is_opened_) {
std::vector<std::string> elems;
split(key, ':', elems);
return atof(ini_.GetValue(elems.front().c_str(), elems.back().c_str(), std::to_string(default_value).c_str()));
} else
return -1.f;
}
void setValue(std::string key, float value) {
if (is_opened_) {
std::vector<std::string> elems;
split(key, ':', elems);
/*SI_Error rc = */ini_.SetValue(elems.front().c_str(), elems.back().c_str(), std::to_string(value).c_str());
}
}
inline bool isOpened() {
return is_opened_;
}
private:
std::string filename_;
bool is_opened_;
CSimpleIniA ini_;
};
bool checkFile(std::string path) {
std::ifstream f(path.c_str());
return f.good();
}
static inline std::string getRootHiddenDir() {
#ifdef WIN32
#ifdef UNICODE
wchar_t szPath[MAX_PATH];
#else
TCHAR szPath[MAX_PATH];
#endif
if (!SUCCEEDED(SHGetFolderPath(NULL, CSIDL_COMMON_APPDATA, NULL, 0, szPath)))
return "";
char snfile_path[MAX_PATH];
#ifndef UNICODE
size_t newsize = strlen(szPath) + 1;
wchar_t * wcstring = new wchar_t[newsize];
// Convert char* string to a wchar_t* string.
size_t convertedChars = 0;
mbstowcs_s(&convertedChars, wcstring, newsize, szPath, _TRUNCATE);
wcstombs(snfile_path, wcstring, MAX_PATH);
#else
wcstombs(snfile_path, szPath, MAX_PATH);
#endif
std::string filename(snfile_path);
filename += "\\Stereolabs\\";
#else //LINUX
std::string homepath = getenv("HOME");
std::string filename = homepath + "/zed/";
#endif
return filename;
}
/*return the path to the Sl ZED hidden dir*/
static inline std::string getHiddenDir() {
std::string filename = getRootHiddenDir();
#ifdef WIN32
filename += "settings\\";
#else //LINUX
filename += "settings/";
#endif
return filename;
}
bool downloadCalibrationFile(unsigned int serial_number, std::string &calibration_file) {
#ifndef _WIN32
std::string path = getHiddenDir();
char specific_name[128];
sprintf(specific_name, "SN%d.conf", serial_number);
calibration_file = path + specific_name;
if (!checkFile(calibration_file)) {
std::string cmd;
int res;
// Create download folder
cmd = "mkdir -p " + path;
res = system(cmd.c_str());
// Download the file
std::string url("'https://calib.stereolabs.com/?SN=");
cmd = "wget " + url + std::to_string(serial_number) + "' -O " + calibration_file;
std::cout << cmd << std::endl;
res = system(cmd.c_str());
if( res == EXIT_FAILURE )
{
std::cerr << "Error downloading the calibration file" << std::endl;
return false;
}
if (!checkFile(calibration_file)) {
std::cerr << "Invalid calibration file" << std::endl;
return false;
}
}
#else
std::string path = getHiddenDir();
char specific_name[128];
sprintf(specific_name, "SN%d.conf", serial_number);
calibration_file = path + specific_name;
if (!checkFile(calibration_file)) {
TCHAR *settingFolder = new TCHAR[path.size() + 1];
settingFolder[path.size()] = 0;
std::copy(path.begin(), path.end(), settingFolder);
SHCreateDirectoryEx(NULL, settingFolder, NULL); //recursive creation
std::string url("https://calib.stereolabs.com/?SN=");
url += std::to_string(serial_number);
TCHAR *address = new TCHAR[url.size() + 1];
address[url.size()] = 0;
std::copy(url.begin(), url.end(), address);
TCHAR *calibPath = new TCHAR[calibration_file.size() + 1];
calibPath[calibration_file.size()] = 0;
std::copy(calibration_file.begin(), calibration_file.end(), calibPath);
HRESULT hr = URLDownloadToFile(NULL, address, calibPath, 0, NULL);
if (hr != 0) {
std::cout << "Fail to download calibration file" << std::endl;
return false;
}
if (!checkFile(calibration_file)) {
std::cout << "Invalid calibration file" << std::endl;
return false;
}
}
#endif
return true;
}
bool initCalibration(std::string calibration_file, cv::Size image_size, rtabmap::StereoCameraModel & model, const rtabmap::Transform & localTransform) {
if (!checkFile(calibration_file)) {
std::cout << "Calibration file missing." << std::endl;
return false;
}
// Open camera configuration file
ConfManager camerareader(calibration_file.c_str());
if (!camerareader.isOpened())
return false;
std::string resolution_str;
switch ((int) image_size.width) {
case 2208:
resolution_str = "2k";
break;
case 1920:
resolution_str = "fhd";
break;
case 1280:
resolution_str = "hd";
break;
case 672:
resolution_str = "vga";
break;
default:
resolution_str = "hd";
break;
}
// Get translations
float T_[3];
T_[0] = camerareader.getValue("stereo:baseline", 0.0f);
T_[1] = camerareader.getValue("stereo:ty_" + resolution_str, 0.f);
if(T_[1] == 0.f)
{
T_[1] = camerareader.getValue("stereo:ty", 0.f);
}
T_[2] = camerareader.getValue("stereo:tz_" + resolution_str, 0.f);
if(T_[2] == 0.f)
{
T_[2] = camerareader.getValue("stereo:tz", 0.f);
}
// Get left parameters
float left_cam_cx = camerareader.getValue("left_cam_" + resolution_str + ":cx", 0.0f);
float left_cam_cy = camerareader.getValue("left_cam_" + resolution_str + ":cy", 0.0f);
float left_cam_fx = camerareader.getValue("left_cam_" + resolution_str + ":fx", 0.0f);
float left_cam_fy = camerareader.getValue("left_cam_" + resolution_str + ":fy", 0.0f);
float left_cam_k1 = camerareader.getValue("left_cam_" + resolution_str + ":k1", 0.0f);
float left_cam_k2 = camerareader.getValue("left_cam_" + resolution_str + ":k2", 0.0f);
float left_cam_p1 = camerareader.getValue("left_cam_" + resolution_str + ":p1", 0.0f);
float left_cam_p2 = camerareader.getValue("left_cam_" + resolution_str + ":p2", 0.0f);
float left_cam_k3 = camerareader.getValue("left_cam_" + resolution_str + ":k3", 0.0f);
// Get right parameters
float right_cam_cx = camerareader.getValue("right_cam_" + resolution_str + ":cx", 0.0f);
float right_cam_cy = camerareader.getValue("right_cam_" + resolution_str + ":cy", 0.0f);
float right_cam_fx = camerareader.getValue("right_cam_" + resolution_str + ":fx", 0.0f);
float right_cam_fy = camerareader.getValue("right_cam_" + resolution_str + ":fy", 0.0f);
float right_cam_k1 = camerareader.getValue("right_cam_" + resolution_str + ":k1", 0.0f);
float right_cam_k2 = camerareader.getValue("right_cam_" + resolution_str + ":k2", 0.0f);
float right_cam_p1 = camerareader.getValue("right_cam_" + resolution_str + ":p1", 0.0f);
float right_cam_p2 = camerareader.getValue("right_cam_" + resolution_str + ":p2", 0.0f);
float right_cam_k3 = camerareader.getValue("right_cam_" + resolution_str + ":k3", 0.0f);
// (Linux only) Safety check A: Wrong "." or "," reading in file conf.
#ifndef _WIN32
if (right_cam_k1 == 0 && left_cam_k1 == 0 && left_cam_k2 == 0 && right_cam_k2 == 0) {
std::cout << "ZED File invalid" << std::endl;
std::string cmd = "rm " + calibration_file;
int res = system(cmd.c_str());
if( res == EXIT_FAILURE )
{
return false;
}
return false;
}
#endif
// Get rotations
cv::Mat R_zed = (cv::Mat_<double>(1, 3) << camerareader.getValue("stereo:rx_" + resolution_str, 0.f), camerareader.getValue("stereo:cv_" + resolution_str, 0.f), camerareader.getValue("stereo:rz_" + resolution_str, 0.f));
//R_zed *= -1.f; // FIXME: we had to invert T below, do we need to do this with R? I don't see much difference looking at the disparity image
cv::Mat R;
cv::Rodrigues(R_zed /*in*/, R /*out*/);
cv::Mat distCoeffs_left, distCoeffs_right;
// Left
cv::Mat cameraMatrix_left = (cv::Mat_<double>(3, 3) << left_cam_fx, 0, left_cam_cx, 0, left_cam_fy, left_cam_cy, 0, 0, 1);
distCoeffs_left = (cv::Mat_<double>(1, 5) << left_cam_k1, left_cam_k2, left_cam_p1, left_cam_p2, left_cam_k3);
// Right
cv::Mat cameraMatrix_right = (cv::Mat_<double>(3, 3) << right_cam_fx, 0, right_cam_cx, 0, right_cam_fy, right_cam_cy, 0, 0, 1);
distCoeffs_right = (cv::Mat_<double>(1, 5) << right_cam_k1, right_cam_k2, right_cam_p1, right_cam_p2, right_cam_k3);
// Stereo
cv::Mat T = (cv::Mat_<double>(3, 1) << T_[0], T_[1], T_[2]);
T /= -1000.f; // convert in meters, inverted to get positive baseline
//std::cout << " Camera Matrix L: \n" << cameraMatrix_left << std::endl << std::endl;
//std::cout << " Camera Matrix R: \n" << cameraMatrix_right << std::endl << std::endl;
//std::cout << " Camera Rotation: \n" << R << std::endl << std::endl;
//std::cout << " Camera Translation: \n" << T << std::endl << std::endl;
cv::Mat R1, R2, P1, P2, Q;
cv::stereoRectify(cameraMatrix_left, distCoeffs_left, cameraMatrix_right, distCoeffs_right, image_size, R, T,
R1, R2, P1, P2, Q, cv::CALIB_ZERO_DISPARITY, 0, image_size);
model = rtabmap::StereoCameraModel("zed",
image_size, cameraMatrix_left, distCoeffs_left, R1, P1,
image_size, cameraMatrix_right, distCoeffs_right, R2, P2,
R, T, cv::Mat(), cv::Mat(), localTransform);
return true;
}
#endif
namespace rtabmap
{
#ifdef RTABMAP_ZEDOC
class ZedOCThread: public UThread
{
public:
ZedOCThread(sl_oc::sensors::SensorCapture* sensCap, const Transform & imuLocalTransform)
{
sensCap_= sensCap;
imuLocalTransform_ = imuLocalTransform;
}
void getIMU(
const double & stamp,
IMU & imu,
int maxWaitTimeMs)
{
imu = IMU();
if(imuBuffer_.empty())
{
return;
}
// Interpolate imu
cv::Vec3d acc;
cv::Vec3d gyr;
int waitTry = 0;
imuMutex_.lock();
while(maxWaitTimeMs > 0 && imuBuffer_.rbegin()->first < stamp && waitTry < maxWaitTimeMs)
{
imuMutex_.unlock();
++waitTry;
uSleep(1);
imuMutex_.lock();
}
bool set = false;
if(imuBuffer_.rbegin()->first < stamp)
{
if(maxWaitTimeMs>0)
{
UWARN("Could not find imu data to interpolate at image time %f after waiting %d ms (last is %f)...", stamp, maxWaitTimeMs, imuBuffer_.rbegin()->first);
}
}
else
{
std::map<double, std::pair<cv::Vec3f, cv::Vec3f> >::const_iterator iterB = imuBuffer_.lower_bound(stamp);
std::map<double, std::pair<cv::Vec3f, cv::Vec3f> >::const_iterator iterA = iterB;
if(iterA != imuBuffer_.begin())
{
iterA = --iterA;
}
if(iterB == imuBuffer_.end())
{
iterB = --iterB;
}
if(iterA == iterB && stamp == iterA->first)
{
acc[0] = iterA->second.first[0];
acc[1] = iterA->second.first[1];
acc[2] = iterA->second.first[2];
gyr[0] = iterA->second.second[0];
gyr[1] = iterA->second.second[1];
gyr[2] = iterA->second.second[2];
set = true;
}
else if(stamp >= iterA->first && stamp <= iterB->first)
{
float t = (stamp-iterA->first) / (iterB->first-iterA->first);
acc[0] = iterA->second.first[0] + t*(iterB->second.first[0] - iterA->second.first[0]);
acc[1] = iterA->second.first[1] + t*(iterB->second.first[1] - iterA->second.first[1]);
acc[2] = iterA->second.first[2] + t*(iterB->second.first[2] - iterA->second.first[2]);
gyr[0] = iterA->second.second[0] + t*(iterB->second.second[0] - iterA->second.second[0]);
gyr[1] = iterA->second.second[1] + t*(iterB->second.second[1] - iterA->second.second[1]);
gyr[2] = iterA->second.second[2] + t*(iterB->second.second[2] - iterA->second.second[2]);
set = true;
}
else
{
if(stamp < iterA->first)
{
UDEBUG("Could not find imu data to interpolate at image time %f (earliest is %f). Are sensors synchronized? (may take some time to be synchronized...)", stamp, iterA->first);
}
else
{
UDEBUG("Could not find imu data to interpolate at image time %f (between %f and %f). Are sensors synchronized? (may take some time to be synchronized...)", stamp, iterA->first, iterB->first);
}
}
}
imuMutex_.unlock();
if(set)
{
imu = IMU(gyr, cv::Mat::eye(3, 3, CV_64FC1),
acc, cv::Mat::eye(3, 3, CV_64FC1),
imuLocalTransform_);
}
return;
}
private:
virtual void mainLoop()
{
// ----> Get IMU data
const sl_oc::sensors::data::Imu imuData = sensCap_->getLastIMUData(2000);
// Process data only if valid
if(imuData.valid == sl_oc::sensors::data::Imu::NEW_VAL ) // Uncomment to use only data syncronized with the video frames
{
UScopeMutex sm(imuMutex_);
static double deg2rad = 0.017453293;
std::pair<cv::Vec3d, cv::Vec3d> imu(
cv::Vec3d(imuData.aX, imuData.aY, imuData.aZ),
cv::Vec3d(imuData.gX*deg2rad, imuData.gY*deg2rad, imuData.gZ*deg2rad));
double stamp = double(imuData.timestamp)/10e8;
if(!imuBuffer_.empty() && imuBuffer_.rbegin()->first > stamp)
{
UWARN("IMU data not received in order, reset buffer! (previous=%f new=%f)", imuBuffer_.rbegin()->first, stamp);
imuBuffer_.clear();
}
imuBuffer_.insert(imuBuffer_.end(), std::make_pair(stamp, imu));
if(imuBuffer_.size() > 1000)
{
imuBuffer_.erase(imuBuffer_.begin());
}
}
}
sl_oc::sensors::SensorCapture* sensCap_;
Transform imuLocalTransform_;
UMutex imuMutex_;
std::map<double, std::pair<cv::Vec3f, cv::Vec3f> > imuBuffer_;
};
#endif
bool CameraStereoZedOC::available()
{
#ifdef RTABMAP_ZEDOC
return true;
#else
return false;
#endif
}
CameraStereoZedOC::CameraStereoZedOC(
int deviceId,
int resolution,
float imageRate,
const Transform & localTransform) :
Camera(imageRate, localTransform)
#ifdef RTABMAP_ZEDOC
,
zed_(0),
sensors_(0),
imuThread_(0),
usbDevice_(deviceId),
resolution_(resolution),
lastStamp_(0)
#endif
{
UDEBUG("");
#ifdef RTABMAP_ZEDOC
sl_oc::video::RESOLUTION res = static_cast<sl_oc::video::RESOLUTION>(resolution_);
UASSERT(res >= sl_oc::video::RESOLUTION::HD2K && res < sl_oc::video::RESOLUTION::LAST);
#endif
}
CameraStereoZedOC::~CameraStereoZedOC()
{
#ifdef RTABMAP_ZEDOC
if(imuThread_)
{
imuThread_->join(true);
delete imuThread_;
}
delete zed_;
delete sensors_;
#endif
}
bool CameraStereoZedOC::init(const std::string & calibrationFolder, const std::string & cameraName)
{
UDEBUG("");
#ifdef RTABMAP_ZEDOC
if(imuThread_)
{
imuThread_->join(true);
delete imuThread_;
imuThread_=0;
}
if(zed_)
{
delete zed_;
zed_ = 0;
}
if(sensors_)
{
delete sensors_;
sensors_ = 0;
}
lastStamp_ = 0;
// ----> Set Video parameters
sl_oc::video::VideoParams params;
params.res = static_cast<sl_oc::video::RESOLUTION>(resolution_);
params.fps = sl_oc::video::FPS::FPS_15;
if(this->getImageRate() > 60)
{
params.fps = sl_oc::video::FPS::FPS_100;
}
else if(this->getImageRate() > 30)
{
params.fps = sl_oc::video::FPS::FPS_60;
}
else if(this->getImageRate() > 15)
{
params.fps = sl_oc::video::FPS::FPS_30;
}
if(ULogger::level() <= ULogger::kInfo)
{
params.verbose = sl_oc::VERBOSITY::INFO;
}
else if(ULogger::level() <= ULogger::kWarning)
{
params.verbose = sl_oc::VERBOSITY::WARNING;
}
// <---- Set Video parameters
// ----> Create Video Capture
zed_ = new sl_oc::video::VideoCapture(params);
if( !zed_->initializeVideo(usbDevice_) )
{
std::cerr << "Cannot open camera video capture" << std::endl;
std::cerr << "See verbosity level for more details." << std::endl;
delete zed_;
zed_ = 0;
return false;
}
int sn = zed_->getSerialNumber();
std::cout << "Connected to camera sn: " << sn << std::endl;
// <---- Create Video Capture
// ----> Retrieve calibration file from Stereolabs server
std::string calibration_file;
// ZED Calibration
unsigned int serial_number = sn;
// Download camera calibration file
if( !downloadCalibrationFile(serial_number, calibration_file) )
{
std::cerr << "Could not load calibration file from Stereolabs servers" << std::endl;
delete zed_;
zed_ = 0;
return false;
}
std::cout << "Calibration file found. Loading..." << std::endl;
// ----> Frame size
int w,h;
zed_->getFrameSize(w,h);
// <---- Frame size
// ----> Initialize calibration
if(initCalibration(calibration_file, cv::Size(w/2,h), stereoModel_, this->getLocalTransform()))
{
std::cout << "Calibration left:" << std::endl << stereoModel_.left() << std::endl;
std::cout << "Calibration right:" << std::endl << stereoModel_.right() << std::endl;
stereoModel_.initRectificationMap();
}
// ----> Create a Sensors Capture object
sensors_ = new sl_oc::sensors::SensorCapture((sl_oc::VERBOSITY)params.verbose);
if( !sensors_->initializeSensors(serial_number) ) // Note: we use the serial number acquired by the VideoCapture object
{
std::cerr << "Cannot open sensors capture" << std::endl;
std::cerr << "Try to enable verbose to get more info" << std::endl;
delete sensors_;
sensors_ = 0;
}
else
{
std::cout << "Sensors Capture connected to camera sn: " << sensors_->getSerialNumber() << std::endl;
// Check is IMU data is available
const sl_oc::sensors::data::Imu& imu = sensors_->getLastIMUData();
if(imu.valid != sl_oc::sensors::data::Imu::NEW_VAL)
{
UINFO("CameraStereoZEDOC: Camera doesn't have IMU sensor");
delete sensors_;
sensors_ = 0;
}
else
{
// Start the sensor capture thread. Note: since sensor data can be retrieved at 400Hz and video data frequency is
// minor (max 100Hz), we use a separated thread for sensors.
// Transform based on ZED2: x->down, y->right, z->backward
Transform imuLocalTransform_ = this->getLocalTransform() * Transform(0,1,0,0, 1,0,0,0, 0,0,-1,0);
std::cout << imuLocalTransform_ << std::endl;
imuThread_ = new ZedOCThread(sensors_, imuLocalTransform_);
// <---- Create Sensors Capture
// ----> Enable video/sensors synchronization
if(!zed_->enableSensorSync(sensors_))
{
UWARN("CameraStereoZEDOC: Failed to start synchronization");
}
// <---- Enable video/sensors synchronization
imuThread_->start();
}
}
return true;
#else
UERROR("CameraStereoZEDOC: RTAB-Map is not built with ZED Open Capture support!");
#endif
return false;
}
bool CameraStereoZedOC::isCalibrated() const
{
#ifdef RTABMAP_ZEDOC
return stereoModel_.isValidForProjection();
#else
return false;
#endif
}
std::string CameraStereoZedOC::getSerial() const
{
#ifdef RTABMAP_ZEDOC
if(zed_)
{
return uFormat("%x", zed_->getSerialNumber());
}
#endif
return "";
}
SensorData CameraStereoZedOC::captureImage(CameraInfo * info)
{
SensorData data;
#ifdef RTABMAP_ZEDOC
// Get a new frame from camera
if(zed_)
{
UTimer timer;
bool imuReceived = true;
do
{
const sl_oc::video::Frame frame = zed_->getLastFrame();
if(frame.data!=nullptr && frame.timestamp!=lastStamp_)
{
lastStamp_ = frame.timestamp;
double stamp = double(lastStamp_)/10e8;
// If the sensor supports IMU, wait IMU to be available before sending data.
IMU imu;
if(imuThread_)
{
imuThread_->getIMU(stamp, imu, 10);
imuReceived = !imu.empty();
}
if(imuReceived)
{
cv::Mat frameBGR, left, right;
// ----> Conversion from YUV 4:2:2 to BGR for visualization
cv::Mat frameYUV = cv::Mat( frame.height, frame.width, CV_8UC2, frame.data );
cv::cvtColor(frameYUV,frameBGR,cv::COLOR_YUV2BGR_YUYV);
// <---- Conversion from YUV 4:2:2 to BGR for visualization
// ----> Extract left and right images from side-by-side
left = frameBGR(cv::Rect(0, 0, frameBGR.cols / 2, frameBGR.rows));
cv::cvtColor(frameBGR(cv::Rect(frameBGR.cols / 2, 0, frameBGR.cols / 2, frameBGR.rows)),right,cv::COLOR_BGR2GRAY);
// <---- Extract left and right images from side-by-side
if(stereoModel_.isValidForRectification())
{
left = stereoModel_.left().rectifyImage(left);
right = stereoModel_.right().rectifyImage(right);
}
data = SensorData(left, right, stereoModel_, this->getNextSeqID(), stamp);
if(!imu.empty())
{
data.setIMU(imu);
}
}
}
else
{
UERROR("CameraStereoZEDOC: Cannot get frame from the camera since 100 msec!");
imuReceived = true;
}
}
while(!imuReceived && timer.elapsed() < 15.0);
// ----> If the frame is valid we can convert, rectify and display it
if(!imuReceived)
{
UERROR("CameraStereoZEDOC: Cannot get synchronized IMU with camera for 15 sec!");
}
}
#else
UERROR("CameraStereoZEDOC: RTAB-Map is not built with ZED Open Capture support!");
#endif
return data;
}
} // namespace rtabmap

View File

@@ -75,6 +75,7 @@ public Q_SLOTS:
void setBoardWidth(int width);
void setBoardHeight(int height);
void setSquareSize(double size);
void setExpectedStereoBaseline(double length);
void setMaxScale(int scale);
void processImages(const cv::Mat & imageLeft, const cv::Mat & imageRight, const QString & cameraName);

View File

@@ -180,6 +180,7 @@ protected Q_SLOTS:
void selectStereoDC1394();
void selectStereoFlyCapture2();
void selectStereoZed();
void selectStereoZedOC();
void selectStereoTara();
void selectStereoUsb();
void selectMyntEyeS();

View File

@@ -105,6 +105,7 @@ public:
kSrcStereoTara = 106,
kSrcStereoRealSense2 = 107,
kSrcStereoMyntEye = 108,
kSrcStereoZedOC = 109,
kSrcRGB = 200,
kSrcUsbDevice = 200,

View File

@@ -43,36 +43,28 @@ AboutDialog::AboutDialog(QWidget * parent) :
_ui = new Ui_aboutDialog();
_ui->setupUi(this);
QString version = Parameters::getVersion().c_str();
#if DEMO_BUILD
version.append(" [DEMO]");
#endif
QString cv_version = CV_VERSION;
#if CV_MAJOR_VERSION < 3
#ifdef RTABMAP_NONFREE
cv_version.append(" [With nonfree]");
_ui->label_opencv_license->setText("Not Commercial");
_ui->label_opencv_license->setText("Not Commercial [With nonfree module]");
#else
cv_version.append(" [Without nonfree]");
_ui->label_opencv_license->setText("BSD");
_ui->label_opencv_license->setText("BSD [Without nonfree module]");
#endif
#elif defined(HAVE_OPENCV_XFEATURES2D)
#ifdef RTABMAP_NONFREE
cv_version.append(" [With xfeatures2d, nonfree]");
_ui->label_opencv_license->setText("Not Commercial");
_ui->label_opencv_license->setText("Not Commercial [With xfeatures2d and nonfree modules]");
#else
cv_version.append(" [With xfeatures2d]");
#if CV_MAJOR_VERSION < 4 || (CV_MAJOR_VERSION==4 && CV_MINOR_VERSION<5)
_ui->label_opencv_license->setText("BSD");
_ui->label_opencv_license->setText("BSD [With xfeatures2d module]");
#else
_ui->label_opencv_license->setText("Apache 3");
_ui->label_opencv_license->setText("Apache 3 [With xfeatures2d module]");
#endif
#endif
#else
cv_version.append(" [Without xfeatures2d and nonfree]");
#if CV_MAJOR_VERSION < 4 || (CV_MAJOR_VERSION==4 && CV_MINOR_VERSION<5)
_ui->label_opencv_license->setText("BSD");
_ui->label_opencv_license->setText("BSD [Without xfeatures2d and nonfree modules]");
#else
_ui->label_opencv_license->setText("Apache 3");
_ui->label_opencv_license->setText("Apache 3 [Without xfeatures2d and nonfree modules]");
#endif
#endif
_ui->label_version->setText(version);
@@ -149,6 +141,8 @@ AboutDialog::AboutDialog(QWidget * parent) :
_ui->label_dc1394_license->setEnabled(CameraStereoDC1394::available());
_ui->label_flycapture2->setText(CameraStereoFlyCapture2::available()?"Yes":"No");
_ui->label_zed->setText(CameraStereoZed::available()?"Yes":"No");
_ui->label_zedOC->setText(CameraStereoZedOC::available()?"Yes":"No");
_ui->label_zedOC_license->setEnabled(CameraStereoZedOC::available());
_ui->label_k4w2->setText(CameraK4W2::available() ? "Yes" : "No");
_ui->label_k4a->setText(CameraK4A::available() ? "Yes" : "No");
_ui->label_mynteye->setText(CameraMyntEye::available() ? "Yes" : "No");

View File

@@ -89,6 +89,7 @@ CalibrationDialog::CalibrationDialog(bool stereo, const QString & savingDirector
connect(ui_->spinBox_boardWidth, SIGNAL(valueChanged(int)), this, SLOT(setBoardWidth(int)));
connect(ui_->spinBox_boardHeight, SIGNAL(valueChanged(int)), this, SLOT(setBoardHeight(int)));
connect(ui_->doubleSpinBox_squareSize, SIGNAL(valueChanged(double)), this, SLOT(setSquareSize(double)));
connect(ui_->doubleSpinBox_stereoBaseline, SIGNAL(valueChanged(double)), this, SLOT(setExpectedStereoBaseline(double)));
connect(ui_->spinBox_maxScale, SIGNAL(valueChanged(int)), this, SLOT(setMaxScale(int)));
connect(ui_->buttonBox, SIGNAL(rejected()), this, SLOT(close()));
@@ -208,6 +209,8 @@ void CalibrationDialog::setStereoMode(bool stereo, const QString & leftSuffix, c
ui_->lineEdit_P_2->setVisible(stereo_);
ui_->radioButton_stereoRectified->setVisible(stereo_);
ui_->checkBox_switchImages->setVisible(stereo_);
ui_->doubleSpinBox_stereoBaseline->setVisible(stereo_);
ui_->label_stereoBaseline->setVisible(stereo_);
}
void CalibrationDialog::setBoardWidth(int width)
@@ -237,6 +240,14 @@ void CalibrationDialog::setSquareSize(double size)
}
}
void CalibrationDialog::setExpectedStereoBaseline(double length)
{
if(length != ui_->doubleSpinBox_stereoBaseline->value())
{
ui_->doubleSpinBox_stereoBaseline->setValue(length);
}
}
void CalibrationDialog::setMaxScale(int scale)
{
if(scale != ui_->spinBox_maxScale->value())
@@ -854,6 +865,22 @@ void CalibrationDialog::calibrate()
if(stereo_ && models_[0].isValidForRectification() && models_[1].isValidForRectification())
{
stereoModel_ = stereoCalibration(models_[0], models_[1], false);
if(stereoModel_.isValidForProjection() &&
ui_->doubleSpinBox_stereoBaseline->value() > 0 &&
stereoModel_.baseline() != ui_->doubleSpinBox_stereoBaseline->value())
{
UWARN("Expected stereo baseline is set to %f m, but computed baseline is %f m. Rescaling baseline...",
stereoModel_.baseline(), ui_->doubleSpinBox_stereoBaseline->value());
cv::Mat P = stereoModel_.right().P().clone();
P.at<double>(0,3) = -P.at<double>(0,0)*ui_->doubleSpinBox_stereoBaseline->value();
stereoModel_ = StereoCameraModel(
stereoModel_.name(),
stereoModel_.left().imageSize(),stereoModel_.left().K_raw(), stereoModel_.left().D_raw(), stereoModel_.left().R(), stereoModel_.left().P(),
stereoModel_.right().imageSize(), stereoModel_.right().K_raw(), stereoModel_.right().D_raw(), stereoModel_.right().R(), P,
stereoModel_.R(), stereoModel_.T(), stereoModel_.E(), stereoModel_.F(), stereoModel_.localTransform());
}
std::stringstream strR1, strP1, strR2, strP2;
strR1 << stereoModel_.left().R();
strP1 << stereoModel_.left().P();
@@ -866,6 +893,18 @@ void CalibrationDialog::calibrate()
ui_->label_baseline->setNum(stereoModel_.baseline());
//ui_->label_error_stereo->setNum(totalAvgErr);
if(!stereoModel_.left().P().empty() &&
!stereoModel_.left().K_raw().empty() &&
fabs(stereoModel_.left().P().at<double>(0,0) - stereoModel_.left().K_raw().at<double>(0,0)) > 5)
{
QMessageBox::warning(this, tr("Stereo Calibration"),
tr("\"fx\" after stereo rectification (%1) is not close from original "
"calibration (%2), the difference would have to be under 5. You may "
"restart the calibration.")
.arg(stereoModel_.left().P().at<double>(0,0))
.arg(stereoModel_.left().K_raw().at<double>(0,0)));
}
}
if(stereo_)

View File

@@ -440,6 +440,7 @@ MainWindow::MainWindow(PreferencesDialog * prefDialog, QWidget * parent, bool sh
connect(_ui->actionStereoDC1394, SIGNAL(triggered()), this, SLOT(selectStereoDC1394()));
connect(_ui->actionStereoFlyCapture2, SIGNAL(triggered()), this, SLOT(selectStereoFlyCapture2()));
connect(_ui->actionStereoZed, SIGNAL(triggered()), this, SLOT(selectStereoZed()));
connect(_ui->actionZed_Open_Capture, SIGNAL(triggered()), this, SLOT(selectStereoZedOC()));
connect(_ui->actionStereoTara, SIGNAL(triggered()), this, SLOT(selectStereoTara()));
connect(_ui->actionStereoUsb, SIGNAL(triggered()), this, SLOT(selectStereoUsb()));
connect(_ui->actionRealSense2_T265, SIGNAL(triggered()), this, SLOT(selectRealSense2Stereo()));
@@ -462,6 +463,7 @@ MainWindow::MainWindow(PreferencesDialog * prefDialog, QWidget * parent, bool sh
_ui->actionStereoDC1394->setEnabled(CameraStereoDC1394::available());
_ui->actionStereoFlyCapture2->setEnabled(CameraStereoFlyCapture2::available());
_ui->actionStereoZed->setEnabled(CameraStereoZed::available());
_ui->actionZed_Open_Capture->setEnabled(CameraStereoZedOC::available());
_ui->actionStereoTara->setEnabled(CameraStereoTara::available());
_ui->actionMYNT_EYE_S_SDK->setEnabled(CameraMyntEye::available());
this->updateSelectSourceMenu();
@@ -4801,6 +4803,7 @@ void MainWindow::updateSelectSourceMenu()
_ui->actionStereoDC1394->setChecked(_preferencesDialog->getSourceDriver() == PreferencesDialog::kSrcDC1394);
_ui->actionStereoFlyCapture2->setChecked(_preferencesDialog->getSourceDriver() == PreferencesDialog::kSrcFlyCapture2);
_ui->actionStereoZed->setChecked(_preferencesDialog->getSourceDriver() == PreferencesDialog::kSrcStereoZed);
_ui->actionZed_Open_Capture->setChecked(_preferencesDialog->getSourceDriver() == PreferencesDialog::kSrcStereoZedOC);
_ui->actionStereoTara->setChecked(_preferencesDialog->getSourceDriver() == PreferencesDialog::kSrcStereoTara);
_ui->actionStereoUsb->setChecked(_preferencesDialog->getSourceDriver() == PreferencesDialog::kSrcStereoUsb);
_ui->actionRealSense2_T265->setChecked(_preferencesDialog->getSourceDriver() == PreferencesDialog::kSrcStereoRealSense2);
@@ -6571,6 +6574,10 @@ void MainWindow::selectStereoZed()
{
_preferencesDialog->selectSourceDriver(PreferencesDialog::kSrcStereoZed);
}
void MainWindow::selectStereoZedOC()
{
_preferencesDialog->selectSourceDriver(PreferencesDialog::kSrcStereoZedOC);
}
void MainWindow::selectStereoTara()
{

View File

@@ -367,6 +367,10 @@ PreferencesDialog::PreferencesDialog(QWidget * parent) :
{
_ui->comboBox_cameraStereo->setItemData(kSrcStereoMyntEye - kSrcStereo, 0, Qt::UserRole - 1);
}
if (!CameraStereoZedOC::available())
{
_ui->comboBox_cameraStereo->setItemData(kSrcStereoZedOC - kSrcStereo, 0, Qt::UserRole - 1);
}
_ui->openni2_exposure->setEnabled(CameraOpenNI2::exposureGainAvailable());
_ui->openni2_gain->setEnabled(CameraOpenNI2::exposureGainAvailable());
@@ -1966,6 +1970,7 @@ void PreferencesDialog::resetSettings(QGroupBox * groupBox)
_ui->spinBox_stereoZed_texturenessConfidenceThr->setValue(90);
_ui->checkbox_stereoZed_odom->setChecked(false);
_ui->lineEdit_zedSvoPath->clear();
_ui->comboBox_stereoZedOC_resolution->setCurrentIndex(3);
_ui->checkbox_stereoRealSense2_odom->setChecked(false);
_ui->checkbox_stereoMyntEye_rectify->setChecked(false);
_ui->checkbox_stereoMyntEye_depth->setChecked(false);
@@ -5002,13 +5007,15 @@ void PreferencesDialog::updateSourceGrpVisibility()
_ui->comboBox_cameraStereo->currentIndex() == kSrcStereoZed - kSrcStereo ||
_ui->comboBox_cameraStereo->currentIndex() == kSrcStereoUsb - kSrcStereo ||
_ui->comboBox_cameraStereo->currentIndex() == kSrcStereoRealSense2 - kSrcStereo ||
_ui->comboBox_cameraStereo->currentIndex() == kSrcStereoMyntEye - kSrcStereo));
_ui->comboBox_cameraStereo->currentIndex() == kSrcStereoMyntEye - kSrcStereo ||
_ui->comboBox_cameraStereo->currentIndex() == kSrcStereoZedOC - kSrcStereo));
_ui->groupBox_cameraStereoImages->setVisible(_ui->comboBox_sourceType->currentIndex() == 1 && _ui->comboBox_cameraStereo->currentIndex() == kSrcStereoImages-kSrcStereo);
_ui->groupBox_cameraStereoVideo->setVisible(_ui->comboBox_sourceType->currentIndex() == 1 && _ui->comboBox_cameraStereo->currentIndex() == kSrcStereoVideo - kSrcStereo);
_ui->groupBox_cameraStereoUsb->setVisible(_ui->comboBox_sourceType->currentIndex() == 1 && _ui->comboBox_cameraStereo->currentIndex() == kSrcStereoUsb - kSrcStereo);
_ui->groupBox_cameraStereoZed->setVisible(_ui->comboBox_sourceType->currentIndex() == 1 && _ui->comboBox_cameraStereo->currentIndex() == kSrcStereoZed - kSrcStereo);
_ui->groupBox_cameraStereoRealSense2->setVisible(_ui->comboBox_sourceType->currentIndex() == 1 && _ui->comboBox_cameraStereo->currentIndex() == kSrcStereoRealSense2 - kSrcStereo);
_ui->groupBox_cameraMyntEye->setVisible(_ui->comboBox_sourceType->currentIndex() == 1 && _ui->comboBox_cameraStereo->currentIndex() == kSrcStereoMyntEye - kSrcStereo);
_ui->groupBox_cameraStereoZedOC->setVisible(_ui->comboBox_sourceType->currentIndex() == 1 && _ui->comboBox_cameraStereo->currentIndex() == kSrcStereoZedOC - kSrcStereo);
_ui->stackedWidget_image->setVisible(_ui->comboBox_sourceType->currentIndex() == 2 &&
(_ui->source_comboBox_image_type->currentIndex() == kSrcImages-kSrcRGB ||
@@ -5037,7 +5044,8 @@ void PreferencesDialog::updateSourceGrpVisibility()
(_ui->comboBox_sourceType->currentIndex() == 0 && _ui->comboBox_cameraRGBD->currentIndex() == kSrcRealSense2 - kSrcRGBD) || //D435i
(_ui->comboBox_sourceType->currentIndex() == 1 && _ui->comboBox_cameraStereo->currentIndex() == kSrcStereoRealSense2 - kSrcStereo) || //T265
(_ui->comboBox_sourceType->currentIndex() == 1 && _ui->comboBox_cameraStereo->currentIndex() == kSrcStereoZed - kSrcStereo) || // ZEDm, ZED2
(_ui->comboBox_sourceType->currentIndex() == 1 && _ui->comboBox_cameraStereo->currentIndex() == kSrcStereoMyntEye - kSrcStereo)); // MYNT EYE S
(_ui->comboBox_sourceType->currentIndex() == 1 && _ui->comboBox_cameraStereo->currentIndex() == kSrcStereoMyntEye - kSrcStereo) || // MYNT EYE S
(_ui->comboBox_sourceType->currentIndex() == 1 && _ui->comboBox_cameraStereo->currentIndex() == kSrcStereoZedOC - kSrcStereo));
_ui->stackedWidget_imuFilter->setVisible(_ui->comboBox_imuFilter_strategy->currentIndex() > 0);
_ui->groupBox_madgwickfilter->setVisible(_ui->comboBox_imuFilter_strategy->currentIndex() == 1);
_ui->groupBox_complementaryfilter->setVisible(_ui->comboBox_imuFilter_strategy->currentIndex() == 2);
@@ -5976,7 +5984,6 @@ Camera * PreferencesDialog::createCamera(bool useRawImages, bool useColor)
this->getSourceLocalTransform());
}
else if (driver == kSrcStereoZed)
{
UDEBUG("ZED");
@@ -6011,6 +6018,15 @@ Camera * PreferencesDialog::createCamera(bool useRawImages, bool useColor)
}
((CameraStereoZed*)camera)->publishInterIMU(_ui->checkbox_publishInterIMU->isChecked());
}
else if (driver == kSrcStereoZedOC)
{
UDEBUG("ZEDOC");
camera = new CameraStereoZedOC(
this->getSourceDevice().isEmpty()?0:atoi(this->getSourceDevice().toStdString().c_str()),
_ui->comboBox_stereoZedOC_resolution->currentIndex(),
this->getGeneralInputRate(),
this->getSourceLocalTransform());
}
else if(driver == kSrcUsbDevice)
{
camera = new CameraVideo(

View File

@@ -162,9 +162,9 @@ p, li { white-space: pre-wrap; }
<property name="geometry">
<rect>
<x>0</x>
<y>-225</y>
<y>-239</y>
<width>596</width>
<height>866</height>
<height>906</height>
</rect>
</property>
<layout class="QVBoxLayout" name="verticalLayout_2">
@@ -188,14 +188,14 @@ p, li { white-space: pre-wrap; }
<item row="16" column="0">
<widget class="QLabel" name="label_21">
<property name="text">
<string>With stereo Zed :</string>
<string>With stereo Zed SDK :</string>
</property>
<property name="wordWrap">
<bool>true</bool>
</property>
</widget>
</item>
<item row="30" column="0">
<item row="31" column="0">
<widget class="QLabel" name="label_25">
<property name="text">
<string>With FOVIS :</string>
@@ -205,7 +205,7 @@ p, li { white-space: pre-wrap; }
</property>
</widget>
</item>
<item row="30" column="2">
<item row="31" column="2">
<widget class="QLabel" name="label_fovis_license">
<property name="text">
<string>GPLv2</string>
@@ -251,7 +251,7 @@ p, li { white-space: pre-wrap; }
</property>
</widget>
</item>
<item row="34" column="0">
<item row="35" column="0">
<widget class="QLabel" name="label_35">
<property name="text">
<string>With OKVIS :</string>
@@ -261,7 +261,7 @@ p, li { white-space: pre-wrap; }
</property>
</widget>
</item>
<item row="32" column="1">
<item row="33" column="1">
<widget class="QLabel" name="label_dvo">
<property name="text">
<string/>
@@ -307,7 +307,7 @@ p, li { white-space: pre-wrap; }
</property>
</widget>
</item>
<item row="34" column="1">
<item row="35" column="1">
<widget class="QLabel" name="label_okvis">
<property name="text">
<string/>
@@ -320,7 +320,7 @@ p, li { white-space: pre-wrap; }
</property>
</widget>
</item>
<item row="36" column="0">
<item row="37" column="0">
<widget class="QLabel" name="label_34">
<property name="text">
<string>With MSCKF :</string>
@@ -330,7 +330,7 @@ p, li { white-space: pre-wrap; }
</property>
</widget>
</item>
<item row="26" column="1">
<item row="27" column="1">
<widget class="QLabel" name="label_octomap">
<property name="text">
<string/>
@@ -343,7 +343,7 @@ p, li { white-space: pre-wrap; }
</property>
</widget>
</item>
<item row="36" column="1">
<item row="37" column="1">
<widget class="QLabel" name="label_msckf">
<property name="text">
<string/>
@@ -376,7 +376,7 @@ p, li { white-space: pre-wrap; }
</property>
</widget>
</item>
<item row="17" column="0">
<item row="18" column="0">
<widget class="QLabel" name="label_38">
<property name="text">
<string>With K4W2 :</string>
@@ -399,7 +399,7 @@ p, li { white-space: pre-wrap; }
</property>
</widget>
</item>
<item row="27" column="0">
<item row="28" column="0">
<widget class="QLabel" name="label_24">
<property name="text">
<string>With CPU-TSDF :</string>
@@ -419,7 +419,7 @@ p, li { white-space: pre-wrap; }
</property>
</widget>
</item>
<item row="31" column="0">
<item row="32" column="0">
<widget class="QLabel" name="label_26">
<property name="text">
<string>With Viso2 :</string>
@@ -429,7 +429,7 @@ p, li { white-space: pre-wrap; }
</property>
</widget>
</item>
<item row="33" column="0">
<item row="34" column="0">
<widget class="QLabel" name="label_28">
<property name="text">
<string>With ORB SLAM 2 :</string>
@@ -449,7 +449,7 @@ p, li { white-space: pre-wrap; }
</property>
</widget>
</item>
<item row="33" column="1">
<item row="34" column="1">
<widget class="QLabel" name="label_orbslam2">
<property name="text">
<string/>
@@ -472,7 +472,7 @@ p, li { white-space: pre-wrap; }
</property>
</widget>
</item>
<item row="31" column="2">
<item row="32" column="2">
<widget class="QLabel" name="label_viso2_license">
<property name="text">
<string>GPLv3</string>
@@ -492,7 +492,7 @@ p, li { white-space: pre-wrap; }
</property>
</widget>
</item>
<item row="26" column="0">
<item row="27" column="0">
<widget class="QLabel" name="label_20">
<property name="text">
<string>With Octomap :</string>
@@ -502,7 +502,7 @@ p, li { white-space: pre-wrap; }
</property>
</widget>
</item>
<item row="20" column="0">
<item row="21" column="0">
<widget class="QLabel" name="label_77">
<property name="text">
<string>With TORO :</string>
@@ -512,7 +512,7 @@ p, li { white-space: pre-wrap; }
</property>
</widget>
</item>
<item row="30" column="1">
<item row="31" column="1">
<widget class="QLabel" name="label_fovis">
<property name="text">
<string/>
@@ -525,7 +525,7 @@ p, li { white-space: pre-wrap; }
</property>
</widget>
</item>
<item row="26" column="2">
<item row="27" column="2">
<widget class="QLabel" name="label_octomap_license">
<property name="text">
<string>BSD</string>
@@ -578,7 +578,7 @@ p, li { white-space: pre-wrap; }
</property>
</widget>
</item>
<item row="27" column="1">
<item row="28" column="1">
<widget class="QLabel" name="label_cputsdf">
<property name="text">
<string/>
@@ -601,7 +601,7 @@ p, li { white-space: pre-wrap; }
</property>
</widget>
</item>
<item row="23" column="0">
<item row="24" column="0">
<widget class="QLabel" name="label_18">
<property name="text">
<string>With cvsba :</string>
@@ -611,7 +611,7 @@ p, li { white-space: pre-wrap; }
</property>
</widget>
</item>
<item row="21" column="0">
<item row="22" column="0">
<widget class="QLabel" name="label_14">
<property name="text">
<string>With g2o :</string>
@@ -621,7 +621,7 @@ p, li { white-space: pre-wrap; }
</property>
</widget>
</item>
<item row="23" column="1">
<item row="24" column="1">
<widget class="QLabel" name="label_cvsba">
<property name="text">
<string/>
@@ -644,7 +644,7 @@ p, li { white-space: pre-wrap; }
</property>
</widget>
</item>
<item row="22" column="1">
<item row="23" column="1">
<widget class="QLabel" name="label_gtsam">
<property name="text">
<string/>
@@ -670,7 +670,7 @@ p, li { white-space: pre-wrap; }
</property>
</widget>
</item>
<item row="22" column="0">
<item row="23" column="0">
<widget class="QLabel" name="label_19">
<property name="text">
<string>With GTSAM :</string>
@@ -736,7 +736,7 @@ p, li { white-space: pre-wrap; }
</property>
</widget>
</item>
<item row="25" column="0">
<item row="26" column="0">
<widget class="QLabel" name="label_29">
<property name="text">
<string>With libpointmatcher :</string>
@@ -746,7 +746,7 @@ p, li { white-space: pre-wrap; }
</property>
</widget>
</item>
<item row="21" column="1">
<item row="22" column="1">
<widget class="QLabel" name="label_g2o">
<property name="text">
<string/>
@@ -795,7 +795,7 @@ p, li { white-space: pre-wrap; }
</property>
</widget>
</item>
<item row="36" column="2">
<item row="37" column="2">
<widget class="QLabel" name="label_msckf_license">
<property name="text">
<string>Penn Software License</string>
@@ -818,7 +818,7 @@ p, li { white-space: pre-wrap; }
</property>
</widget>
</item>
<item row="32" column="2">
<item row="33" column="2">
<widget class="QLabel" name="label_dvo_license">
<property name="text">
<string>GPLv3</string>
@@ -828,7 +828,7 @@ p, li { white-space: pre-wrap; }
</property>
</widget>
</item>
<item row="35" column="0">
<item row="36" column="0">
<widget class="QLabel" name="label_36">
<property name="text">
<string>With loam_velodyne :</string>
@@ -861,7 +861,7 @@ p, li { white-space: pre-wrap; }
</property>
</widget>
</item>
<item row="28" column="1">
<item row="29" column="1">
<widget class="QLabel" name="label_openchisel">
<property name="text">
<string/>
@@ -874,7 +874,7 @@ p, li { white-space: pre-wrap; }
</property>
</widget>
</item>
<item row="22" column="2">
<item row="23" column="2">
<widget class="QLabel" name="label_gtsam_license">
<property name="text">
<string>BSD</string>
@@ -884,7 +884,7 @@ p, li { white-space: pre-wrap; }
</property>
</widget>
</item>
<item row="25" column="1">
<item row="26" column="1">
<widget class="QLabel" name="label_libpointmatcher">
<property name="text">
<string/>
@@ -897,7 +897,7 @@ p, li { white-space: pre-wrap; }
</property>
</widget>
</item>
<item row="35" column="1">
<item row="36" column="1">
<widget class="QLabel" name="label_loam">
<property name="text">
<string/>
@@ -920,7 +920,7 @@ p, li { white-space: pre-wrap; }
</property>
</widget>
</item>
<item row="32" column="0">
<item row="33" column="0">
<widget class="QLabel" name="label_27">
<property name="text">
<string>With DVO :</string>
@@ -930,7 +930,7 @@ p, li { white-space: pre-wrap; }
</property>
</widget>
</item>
<item row="31" column="1">
<item row="32" column="1">
<widget class="QLabel" name="label_viso2">
<property name="text">
<string/>
@@ -943,7 +943,7 @@ p, li { white-space: pre-wrap; }
</property>
</widget>
</item>
<item row="33" column="2">
<item row="34" column="2">
<widget class="QLabel" name="label_orbslam2_license">
<property name="text">
<string>GPLv3</string>
@@ -953,7 +953,7 @@ p, li { white-space: pre-wrap; }
</property>
</widget>
</item>
<item row="28" column="0">
<item row="29" column="0">
<widget class="QLabel" name="label_30">
<property name="text">
<string>With OpenChisel :</string>
@@ -976,7 +976,7 @@ p, li { white-space: pre-wrap; }
</property>
</widget>
</item>
<item row="20" column="1">
<item row="21" column="1">
<widget class="QLabel" name="label_toro">
<property name="text">
<string/>
@@ -989,7 +989,7 @@ p, li { white-space: pre-wrap; }
</property>
</widget>
</item>
<item row="21" column="2">
<item row="22" column="2">
<widget class="QLabel" name="label_g2o_license">
<property name="text">
<string>BSD</string>
@@ -999,7 +999,7 @@ p, li { white-space: pre-wrap; }
</property>
</widget>
</item>
<item row="34" column="2">
<item row="35" column="2">
<widget class="QLabel" name="label_okvis_license">
<property name="text">
<string>BSD</string>
@@ -1009,7 +1009,7 @@ p, li { white-space: pre-wrap; }
</property>
</widget>
</item>
<item row="35" column="2">
<item row="36" column="2">
<widget class="QLabel" name="label_loam_license">
<property name="text">
<string>BSD</string>
@@ -1039,7 +1039,7 @@ p, li { white-space: pre-wrap; }
</property>
</widget>
</item>
<item row="25" column="2">
<item row="26" column="2">
<widget class="QLabel" name="label_libpointmatcher_license">
<property name="text">
<string>BSD</string>
@@ -1049,7 +1049,7 @@ p, li { white-space: pre-wrap; }
</property>
</widget>
</item>
<item row="27" column="2">
<item row="28" column="2">
<widget class="QLabel" name="label_cputsdf_license">
<property name="text">
<string>BSD</string>
@@ -1069,7 +1069,7 @@ p, li { white-space: pre-wrap; }
</property>
</widget>
</item>
<item row="23" column="2">
<item row="24" column="2">
<widget class="QLabel" name="label_cvsba_license">
<property name="text">
<string>GPLv2</string>
@@ -1079,7 +1079,7 @@ p, li { white-space: pre-wrap; }
</property>
</widget>
</item>
<item row="20" column="2">
<item row="21" column="2">
<widget class="QLabel" name="label_toro_license">
<property name="text">
<string>Creative Commons [Attribution-NonCommercial-ShareAlike]</string>
@@ -1112,7 +1112,7 @@ p, li { white-space: pre-wrap; }
</property>
</widget>
</item>
<item row="18" column="0">
<item row="19" column="0">
<widget class="QLabel" name="label_68">
<property name="text">
<string>With K4A :</string>
@@ -1122,7 +1122,7 @@ p, li { white-space: pre-wrap; }
</property>
</widget>
</item>
<item row="17" column="1">
<item row="18" column="1">
<widget class="QLabel" name="label_k4w2">
<property name="text">
<string/>
@@ -1135,7 +1135,7 @@ p, li { white-space: pre-wrap; }
</property>
</widget>
</item>
<item row="18" column="1">
<item row="19" column="1">
<widget class="QLabel" name="label_k4a">
<property name="text">
<string/>
@@ -1148,7 +1148,7 @@ p, li { white-space: pre-wrap; }
</property>
</widget>
</item>
<item row="18" column="2">
<item row="19" column="2">
<widget class="QLabel" name="label_g2o_license_3">
<property name="text">
<string>MIT</string>
@@ -1191,7 +1191,7 @@ p, li { white-space: pre-wrap; }
</property>
</widget>
</item>
<item row="24" column="0">
<item row="25" column="0">
<widget class="QLabel" name="label_40">
<property name="text">
<string>With Ceres :</string>
@@ -1201,7 +1201,7 @@ p, li { white-space: pre-wrap; }
</property>
</widget>
</item>
<item row="24" column="2">
<item row="25" column="2">
<widget class="QLabel" name="label_ceres_license">
<property name="text">
<string>BSD</string>
@@ -1211,7 +1211,7 @@ p, li { white-space: pre-wrap; }
</property>
</widget>
</item>
<item row="24" column="1">
<item row="25" column="1">
<widget class="QLabel" name="label_ceres">
<property name="text">
<string/>
@@ -1224,7 +1224,7 @@ p, li { white-space: pre-wrap; }
</property>
</widget>
</item>
<item row="29" column="0">
<item row="30" column="0">
<widget class="QLabel" name="label_41">
<property name="text">
<string>With AliceVision :</string>
@@ -1234,7 +1234,7 @@ p, li { white-space: pre-wrap; }
</property>
</widget>
</item>
<item row="29" column="1">
<item row="30" column="1">
<widget class="QLabel" name="label_aliceVision">
<property name="text">
<string/>
@@ -1247,7 +1247,7 @@ p, li { white-space: pre-wrap; }
</property>
</widget>
</item>
<item row="29" column="2">
<item row="30" column="2">
<widget class="QLabel" name="label_aliceVision_license">
<property name="text">
<string>MPL2</string>
@@ -1323,7 +1323,7 @@ p, li { white-space: pre-wrap; }
</property>
</widget>
</item>
<item row="19" column="0">
<item row="20" column="0">
<widget class="QLabel" name="label_69">
<property name="text">
<string>With MYNTEYE S :</string>
@@ -1333,7 +1333,7 @@ p, li { white-space: pre-wrap; }
</property>
</widget>
</item>
<item row="19" column="1">
<item row="20" column="1">
<widget class="QLabel" name="label_mynteye">
<property name="text">
<string/>
@@ -1346,6 +1346,39 @@ p, li { white-space: pre-wrap; }
</property>
</widget>
</item>
<item row="17" column="0">
<widget class="QLabel" name="label_44">
<property name="text">
<string>With stereo Zed Open Capture :</string>
</property>
<property name="wordWrap">
<bool>true</bool>
</property>
</widget>
</item>
<item row="17" column="1">
<widget class="QLabel" name="label_zedOC">
<property name="text">
<string/>
</property>
<property name="alignment">
<set>Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter</set>
</property>
<property name="wordWrap">
<bool>true</bool>
</property>
</widget>
</item>
<item row="17" column="2">
<widget class="QLabel" name="label_zedOC_license">
<property name="text">
<string>MIT</string>
</property>
<property name="wordWrap">
<bool>true</bool>
</property>
</widget>
</item>
</layout>
</item>
</layout>

View File

@@ -17,7 +17,16 @@
<property name="spacing">
<number>0</number>
</property>
<property name="margin">
<property name="leftMargin">
<number>0</number>
</property>
<property name="topMargin">
<number>0</number>
</property>
<property name="rightMargin">
<number>0</number>
</property>
<property name="bottomMargin">
<number>0</number>
</property>
<item>
@@ -145,12 +154,21 @@
<rect>
<x>0</x>
<y>0</y>
<width>379</width>
<height>816</height>
<width>387</width>
<height>826</height>
</rect>
</property>
<layout class="QVBoxLayout" name="verticalLayout">
<property name="margin">
<property name="leftMargin">
<number>0</number>
</property>
<property name="topMargin">
<number>0</number>
</property>
<property name="rightMargin">
<number>0</number>
</property>
<property name="bottomMargin">
<number>0</number>
</property>
<item>
@@ -271,6 +289,35 @@
</property>
</widget>
</item>
<item row="5" column="0">
<widget class="QLabel" name="label_stereoBaseline">
<property name="toolTip">
<string>If &gt; 1, image is scaled down to help board detection on high definition images</string>
</property>
<property name="text">
<string>Stereo Baseline</string>
</property>
</widget>
</item>
<item row="5" column="1">
<widget class="QDoubleSpinBox" name="doubleSpinBox_stereoBaseline">
<property name="toolTip">
<string>If you know the exact baseline of the stereo cameras, you can set it here in case the square size is not super accurate.</string>
</property>
<property name="suffix">
<string> m</string>
</property>
<property name="decimals">
<number>4</number>
</property>
<property name="maximum">
<double>10.000000000000000</double>
</property>
<property name="value">
<double>0.000000000000000</double>
</property>
</widget>
</item>
</layout>
</widget>
</item>

View File

@@ -267,6 +267,7 @@
<normaloff>:/images/zed.png</normaloff>:/images/zed.png</iconset>
</property>
<addaction name="actionStereoZed"/>
<addaction name="actionZed_Open_Capture"/>
<addaction name="actionStereoUsb"/>
</widget>
<widget class="QMenu" name="menuTara_Camera">
@@ -1617,6 +1618,14 @@
<string>RealSense2</string>
</property>
</action>
<action name="actionZed_Open_Capture">
<property name="checkable">
<bool>true</bool>
</property>
<property name="text">
<string>Zed Open Capture</string>
</property>
</action>
</widget>
<customwidgets>
<customwidget>

View File

@@ -63,7 +63,7 @@
<property name="geometry">
<rect>
<x>0</x>
<y>-673</y>
<y>-555</y>
<width>686</width>
<height>3357</height>
</rect>
@@ -4816,6 +4816,11 @@ when using the file type, logs are saved in LogRtabmap.txt (located in the worki
<string>MyntEyeS</string>
</property>
</item>
<item>
<property name="text">
<string>ZED Open Capture</string>
</property>
</item>
</widget>
</item>
<item row="0" column="2">
@@ -4896,7 +4901,7 @@ when using the file type, logs are saved in LogRtabmap.txt (located in the worki
<item>
<widget class="QStackedWidget" name="stackedWidget_stereo">
<property name="currentIndex">
<number>5</number>
<number>9</number>
</property>
<widget class="QWidget" name="page_49">
<layout class="QVBoxLayout" name="verticalLayout_91">
@@ -5728,6 +5733,75 @@ when using the file type, logs are saved in LogRtabmap.txt (located in the worki
</item>
</layout>
</widget>
<widget class="QWidget" name="page_88">
<layout class="QVBoxLayout" name="verticalLayout_154">
<item>
<widget class="QGroupBox" name="groupBox_cameraStereoZedOC">
<property name="sizePolicy">
<sizepolicy hsizetype="Ignored" vsizetype="Ignored">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="title">
<string>Zed Open Capture</string>
</property>
<layout class="QGridLayout" name="gridLayout_119" columnstretch="0,1">
<item row="0" column="0">
<widget class="QComboBox" name="comboBox_stereoZedOC_resolution">
<item>
<property name="text">
<string>HD2K</string>
</property>
</item>
<item>
<property name="text">
<string>HD1080</string>
</property>
</item>
<item>
<property name="text">
<string>HD720</string>
</property>
</item>
<item>
<property name="text">
<string>VGA</string>
</property>
</item>
</widget>
</item>
<item row="1" column="0">
<spacer name="verticalSpacer_70">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>0</height>
</size>
</property>
</spacer>
</item>
<item row="0" column="1">
<widget class="QLabel" name="label_624">
<property name="text">
<string>Resolution.</string>
</property>
<property name="wordWrap">
<bool>true</bool>
</property>
<property name="textInteractionFlags">
<set>Qt::LinksAccessibleByMouse|Qt::TextSelectableByMouse</set>
</property>
</widget>
</item>
</layout>
</widget>
</item>
</layout>
</widget>
</widget>
</item>
</layout>

View File

@@ -63,6 +63,7 @@ void showUsage()
" 11=RealSense2\n"
" 12=Kinect for Azure SDK\n"
" 13=MYNT EYE S\n"
" 14=ZED Open Capture\n"
" Options:\n"
" -rate #.# Input rate Hz (default 0=inf)\n"
" -device # Device ID (number or string)\n"
@@ -174,9 +175,9 @@ int main(int argc, char * argv[])
// last
driver = atoi(argv[i]);
if(driver < 0 || driver > 13)
if(driver < 0 || driver > 14)
{
UERROR("driver should be between 0 and 13.");
UERROR("driver should be between 0 and 14.");
showUsage();
}
}
@@ -314,6 +315,15 @@ int main(int argc, char * argv[])
}
camera = new rtabmap::CameraMyntEye(deviceId);
}
else if (driver == 14)
{
if (!rtabmap::CameraStereoZedOC::available())
{
UERROR("Not built with Zed Open Capture support...");
exit(-1);
}
camera = new rtabmap::CameraStereoZedOC(uStr2Int(deviceId));
}
else
{
UFATAL("");