Compare commits

..

16 Commits

Author SHA1 Message Date
matlabbe
9c91fb8cd8 0.17.1: Fixed issue #282 and https://github.com/introlab/rtabmap_ros/issues/243 2018-05-14 20:50:21 +00:00
matlabbe
5cdede1482 fixed a compilation warning 2018-05-10 13:57:02 -04:00
matlabbe
fa174be741 Updated rtabmap-kitti tool 2018-05-10 13:14:07 -04:00
matlabbe
5e93803eef GUI: Fixed "map id of node -1 not found" error when enabling nodes filtering (https://github.com/introlab/rtabmap_ros/issues/235) 2018-05-08 20:05:29 -04:00
matlabbe
bb0b12be27 Updated not incremental dictionary approach for save/reload (can set a database path as dictionary for convenience) 2018-05-08 18:50:39 -04:00
matlabbe
41e93ac6f0 Docker: re-added post_push so that additional tags are pushed with automated build 2018-05-07 09:28:08 -04:00
matlabbe
1df99efa14 Docker: added --cache-from to use cache 2018-05-06 23:46:04 -04:00
matlabbe
911b8158a4 Docker: added post_push hooks to add tags 2018-05-06 17:42:30 -04:00
matlabbe
e875c7d6d1 Docker: android scripts updated 2018-05-04 19:52:11 -04:00
matlabbe
0ddbb28fd2 RGBD example: added code example to generate/update the global occupancy grid from rtabmap events. 2018-05-04 19:13:07 -04:00
matlabbe
e54234ec50 Docker: fixing missing tag in automated build 2018-05-04 09:25:17 -04:00
matlabbe
6dd0cd27e1 Docker: added quotes around date, updated install_deps to use saved pwd instead of cd alone to return to root 2018-05-03 18:06:37 -04:00
matlabbe
ec50b0c366 Docker: added hooks for main docker images 2018-05-03 09:11:27 -04:00
matlabbe
97b61f885d Docker: added hooks/build to xenial build with CACHE_DATE 2018-05-03 08:56:47 -04:00
matlabbe
0d7b8f13d8 Docker replaced -j3 by -j8 2018-05-02 16:19:15 -04:00
matlabbe
2bf7d87b29 Docker: add g2o/gtsam/libpointmatcher to dockerfiles 2018-05-02 16:10:36 -04:00
31 changed files with 647 additions and 277 deletions

View File

@@ -21,7 +21,7 @@ SET(CMAKE_MODULE_PATH "${PROJECT_SOURCE_DIR}/cmake_modules")
#######################
SET(RTABMAP_MAJOR_VERSION 0)
SET(RTABMAP_MINOR_VERSION 17)
SET(RTABMAP_PATCH_VERSION 0)
SET(RTABMAP_PATCH_VERSION 1)
SET(RTABMAP_VERSION
${RTABMAP_MAJOR_VERSION}.${RTABMAP_MINOR_VERSION}.${RTABMAP_PATCH_VERSION})

View File

@@ -39,9 +39,14 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include <pcl/pcl_config.h>
#ifdef HAVE_OPENNI
#if __linux__ && __i386__ && __cplusplus >= 201103L
#warning "Openni driver is not available on i386 when building with c++11 support"
#else
#define RTABMAP_OPENNI
#include <pcl/io/openni_camera/openni_depth_image.h>
#include <pcl/io/openni_camera/openni_image.h>
#endif
#endif
#include <boost/signals2/connection.hpp>
@@ -102,7 +107,7 @@ public:
float imageRate = 0,
const Transform & localTransform = Transform::getIdentity());
virtual ~CameraOpenni();
#ifdef HAVE_OPENNI
#ifdef RTABMAP_OPENNI
void image_cb (
const boost::shared_ptr<openni_wrapper::Image>& rgb,
const boost::shared_ptr<openni_wrapper::DepthImage>& depth,

View File

@@ -155,7 +155,7 @@ public:
void executeNoResult(const std::string & sql) const;
// Load objects
void load(VWDictionary * dictionary) const;
void load(VWDictionary * dictionary, bool lastStateOnly = true) const;
void loadLastNodes(std::list<Signature *> & signatures) const;
void loadSignatures(const std::list<int> & ids, std::list<Signature *> & signatures, std::set<int> * loadedFromTrash = 0);
void loadWords(const std::set<int> & wordIds, std::list<VisualWord *> & vws);
@@ -255,7 +255,7 @@ private:
cv::Mat * textures) const = 0;
// Load objects
virtual void loadQuery(VWDictionary * dictionary) const = 0;
virtual void loadQuery(VWDictionary * dictionary, bool lastStateOnly = true) const = 0;
virtual void loadLastNodesQuery(std::list<Signature *> & signatures) const = 0;
virtual void loadSignaturesQuery(const std::list<int> & ids, std::list<Signature *> & signatures) const = 0;
virtual void loadWordsQuery(const std::set<int> & wordIds, std::list<VisualWord *> & vws) const = 0;

View File

@@ -39,7 +39,7 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include <rtabmap/utilite/UTimer.h>
#include <rtabmap/utilite/UMath.h>
#ifdef HAVE_OPENNI
#ifdef RTABMAP_OPENNI
#include <pcl/io/openni_grabber.h>
#include <pcl/io/oni_grabber.h>
#include <pcl/io/openni_camera/openni_depth_image.h>
@@ -97,7 +97,7 @@ CameraOpenni::CameraOpenni(const std::string & deviceId, float imageRate, const
bool CameraOpenni::available()
{
#ifdef HAVE_OPENNI
#ifdef RTABMAP_OPENNI
return true;
#else
return false;
@@ -106,7 +106,7 @@ bool CameraOpenni::available()
CameraOpenni::~CameraOpenni()
{
#ifdef HAVE_OPENNI
#ifdef RTABMAP_OPENNI
UDEBUG("");
if(connection_.connected())
{
@@ -122,7 +122,7 @@ CameraOpenni::~CameraOpenni()
}
#endif
}
#ifdef HAVE_OPENNI
#ifdef RTABMAP_OPENNI
void CameraOpenni::image_cb (
const boost::shared_ptr<openni_wrapper::Image>& rgb,
const boost::shared_ptr<openni_wrapper::DepthImage>& depth,
@@ -150,7 +150,7 @@ void CameraOpenni::image_cb (
bool CameraOpenni::init(const std::string & calibrationFolder, const std::string & cameraName)
{
#ifdef HAVE_OPENNI
#ifdef RTABMAP_OPENNI
if(interface_)
{
interface_->stop();
@@ -197,7 +197,7 @@ bool CameraOpenni::init(const std::string & calibrationFolder, const std::string
bool CameraOpenni::isCalibrated() const
{
#ifdef HAVE_OPENNI
#ifdef RTABMAP_OPENNI
return true;
#else
return false;
@@ -206,7 +206,7 @@ bool CameraOpenni::isCalibrated() const
std::string CameraOpenni::getSerial() const
{
#ifdef HAVE_OPENNI
#ifdef RTABMAP_OPENNI
if(interface_)
{
return interface_->getName();
@@ -218,7 +218,7 @@ std::string CameraOpenni::getSerial() const
SensorData CameraOpenni::captureImage(CameraInfo * info)
{
SensorData data;
#ifdef HAVE_OPENNI
#ifdef RTABMAP_OPENNI
if(interface_ && interface_->isRunning())
{
if(!dataReady_.acquire(1, 5000))

View File

@@ -436,7 +436,7 @@ void DBDriver::saveOrUpdate(const std::vector<Signature *> & signatures)
void DBDriver::saveOrUpdate(const std::vector<VisualWord *> & words) const
{
ULOGGER_DEBUG("");
ULOGGER_DEBUG("words.size=%d", (int)words.size());
std::list<VisualWord *> toSave;
std::list<VisualWord *> toUpdate;
if(this->isConnected() && words.size())
@@ -511,10 +511,10 @@ void DBDriver::updateDepthImage(int nodeId, const cv::Mat & image)
_dbSafeAccessMutex.unlock();
}
void DBDriver::load(VWDictionary * dictionary) const
void DBDriver::load(VWDictionary * dictionary, bool lastStateOnly) const
{
_dbSafeAccessMutex.lock();
this->loadQuery(dictionary);
this->loadQuery(dictionary, lastStateOnly);
_dbSafeAccessMutex.unlock();
}

View File

@@ -3077,7 +3077,7 @@ void DBDriverSqlite3::loadLastNodesQuery(std::list<Signature *> & nodes) const
}
}
void DBDriverSqlite3::loadQuery(VWDictionary * dictionary) const
void DBDriverSqlite3::loadQuery(VWDictionary * dictionary, bool lastStateOnly) const
{
ULOGGER_DEBUG("");
if(_ppDb && dictionary)
@@ -3087,26 +3087,25 @@ void DBDriverSqlite3::loadQuery(VWDictionary * dictionary) const
timer.start();
int rc = SQLITE_OK;
sqlite3_stmt * ppStmt = 0;
std::string query;
std::stringstream query;
std::list<VisualWord *> visualWords;
// Get the visual words
if(uStrNumCmp(_version, "0.11.11") >= 0)
query << "SELECT id, descriptor_size, descriptor FROM Word ";
if(lastStateOnly)
{
query = "SELECT id, descriptor_size, descriptor "
"FROM Word "
"WHERE time_enter >= (SELECT MAX(time_enter) FROM Info) "
"ORDER BY id;";
}
else
{
query = "SELECT id, descriptor_size, descriptor "
"FROM Word "
"WHERE time_enter >= (SELECT MAX(time_enter) FROM Statistics) "
"ORDER BY id;";
if(uStrNumCmp(_version, "0.11.11") >= 0)
{
query << "WHERE time_enter >= (SELECT MAX(time_enter) FROM Info) ";
}
else
{
query << "WHERE time_enter >= (SELECT MAX(time_enter) FROM Statistics) ";
}
}
query << "ORDER BY id;";
rc = sqlite3_prepare_v2(_ppDb, query.c_str(), -1, &ppStmt, 0);
rc = sqlite3_prepare_v2(_ppDb, query.str().c_str(), -1, &ppStmt, 0);
UASSERT_MSG(rc == SQLITE_OK, uFormat("DB error (%s): %s", _version.c_str(), sqlite3_errmsg(_ppDb)).c_str());
// Process the result if one

View File

@@ -124,7 +124,7 @@ private:
cv::Mat * textures) const;
// Load objects
virtual void loadQuery(VWDictionary * dictionary) const;
virtual void loadQuery(VWDictionary * dictionary, bool lastStateOnly = true) const;
virtual void loadLastNodesQuery(std::list<Signature *> & signatures) const;
virtual void loadSignaturesQuery(const std::list<int> & ids, std::list<Signature *> & signatures) const;
virtual void loadWordsQuery(const std::set<int> & wordIds, std::list<VisualWord *> & vws) const;

View File

@@ -279,25 +279,32 @@ void Memory::loadDataFromDb(bool postInitClosingEvents)
}
UDEBUG("load words %d", (int)wordIds.size());
if(wordIds.size())
if(_vwd->isIncremental())
{
std::list<VisualWord*> words;
_dbDriver->loadWords(wordIds, words);
for(std::list<VisualWord*>::iterator iter = words.begin(); iter!=words.end(); ++iter)
if(wordIds.size())
{
_vwd->addWord(*iter);
std::list<VisualWord*> words;
_dbDriver->loadWords(wordIds, words);
for(std::list<VisualWord*>::iterator iter = words.begin(); iter!=words.end(); ++iter)
{
_vwd->addWord(*iter);
}
// Get Last word id
int id = 0;
_dbDriver->getLastWordId(id);
_vwd->setLastWordId(id);
}
// Get Last word id
int id = 0;
_dbDriver->getLastWordId(id);
_vwd->setLastWordId(id);
}
else
{
_dbDriver->load(_vwd, false);
}
}
else
{
UDEBUG("load words");
// load the last dictionary
_dbDriver->load(_vwd);
_dbDriver->load(_vwd, _vwd->isIncremental());
}
UDEBUG("%d words loaded!", _vwd->getUnusedWordsSize());
_vwd->update();
@@ -649,7 +656,10 @@ void Memory::parseParameters(const ParametersMap & parameters)
void Memory::preUpdate()
{
_signaturesAdded = 0;
this->cleanUnusedWords();
if(_vwd->isIncremental())
{
this->cleanUnusedWords();
}
if(_vwd && !_parallelized)
{
//When parallelized, it is done in CreateSignature
@@ -1584,7 +1594,7 @@ std::map<int, float> Memory::computeLikelihood(const Signature * signature, cons
{
// "Inverted index" - Pour chaque endroit contenu dans chaque mot
vw = _vwd->getWord(*i);
UASSERT(vw!=0);
UASSERT_MSG(vw!=0, uFormat("Word %d not found in dictionary!?", *i).c_str());
const std::map<int, int> & refs = vw->getReferences();
nw = refs.size();
@@ -2055,7 +2065,7 @@ void Memory::moveToTrash(Signature * s, bool keepLinkedToGraph, std::list<int> *
}
this->disableWordsRef(s->id());
if(!keepLinkedToGraph)
if(!keepLinkedToGraph && _vwd->isIncremental())
{
std::list<int> keys = uUniqueKeys(s->getWords());
for(std::list<int>::const_iterator i=keys.begin(); i!=keys.end(); ++i)
@@ -4217,25 +4227,22 @@ void Memory::disableWordsRef(int signatureId)
void Memory::cleanUnusedWords()
{
if(_vwd->isIncremental())
std::vector<VisualWord*> removedWords = _vwd->getUnusedWords();
UDEBUG("Removing %d words (dictionary size=%d)...", removedWords.size(), _vwd->getVisualWords().size());
if(removedWords.size())
{
std::vector<VisualWord*> removedWords = _vwd->getUnusedWords();
UDEBUG("Removing %d words (dictionary size=%d)...", removedWords.size(), _vwd->getVisualWords().size());
if(removedWords.size())
{
// remove them from the dictionary
_vwd->removeWords(removedWords);
// remove them from the dictionary
_vwd->removeWords(removedWords);
for(unsigned int i=0; i<removedWords.size(); ++i)
for(unsigned int i=0; i<removedWords.size(); ++i)
{
if(_dbDriver)
{
if(_dbDriver)
{
_dbDriver->asyncSave(removedWords[i]);
}
else
{
delete removedWords[i];
}
_dbDriver->asyncSave(removedWords[i]);
}
else
{
delete removedWords[i];
}
}
}
@@ -4270,6 +4277,11 @@ void Memory::enableWordsRef(const std::list<int> & signatureIds)
}
}
if(!_vwd->isIncremental() && oldWordIds.size())
{
UWARN("Dictionary is fixed, but some words retrieved have not been found!?");
}
UDEBUG("oldWordIds.size()=%d, getOldIds time=%fs", oldWordIds.size(), timer.ticks());
// the words were deleted, so try to math it with an active word

View File

@@ -136,7 +136,8 @@ ParametersMap Parameters::deserialize(const std::string & parameters)
}
if(Parameters::getDefaultParameters().find(key) == Parameters::getDefaultParameters().end())
if(oldIter==Parameters::getRemovedParameters().end() &&
Parameters::getDefaultParameters().find(key) == Parameters::getDefaultParameters().end())
{
UWARN("Unknown parameter \"%s\"=\"%s\"! The parameter is still added to output map.", key.c_str(), value.c_str());
}

View File

@@ -142,79 +142,119 @@ void VWDictionary::setFixedDictionary(const std::string & dictionaryPath)
if((!_incrementalDictionary && _dictionaryPath.compare(dictionaryPath) != 0) ||
_visualWords.size() == 0)
{
std::ifstream file;
file.open(dictionaryPath.c_str(), std::ifstream::in);
if(file.good())
UDEBUG("incremental=%d, oldPath=%s newPath=%s, visual words=%d",
_incrementalDictionary?1:0, _dictionaryPath.c_str(), dictionaryPath.c_str(), (int)_visualWords.size());
if(UFile::getExtension(dictionaryPath).compare("db") == 0)
{
UDEBUG("Deleting old dictionary and loading the new one from \"%s\"", dictionaryPath.c_str());
UTimer timer;
// first line is the header
std::string str;
std::list<std::string> strList;
std::getline(file, str);
strList = uSplitNumChar(str);
unsigned int dimension = 0;
for(std::list<std::string>::iterator iter = strList.begin(); iter != strList.end(); ++iter)
UDEBUG("Loading fixed vocabulary \"%s\", this may take a while...", dictionaryPath.c_str());
DBDriver * driver = DBDriver::create();
if(driver->openConnection(dictionaryPath, false))
{
if(uIsDigit(iter->at(0)))
driver->load(this, false);
for(std::map<int, VisualWord*>::iterator iter=_visualWords.begin(); iter!=_visualWords.end(); ++iter)
{
dimension = std::atoi(iter->c_str());
break;
iter->second->setSaved(false);
}
}
if(dimension == 0 || dimension > 1000)
{
UERROR("Invalid dictionary file, visual word dimension (%d) is not valid, \"%s\"", dimension, dictionaryPath.c_str());
_incrementalDictionary = _visualWords.size()==0;
driver->closeConnection(false);
}
else
{
// Process all words
while(file.good())
{
std::getline(file, str);
strList = uSplit(str);
if(strList.size() == dimension+1)
{
//first one is the visual word id
std::list<std::string>::iterator iter = strList.begin();
int id = std::atoi(iter->c_str());
cv::Mat descriptor(1, dimension, CV_32F);
++iter;
unsigned int i=0;
//get descriptor
for(;i<dimension && iter != strList.end(); ++i, ++iter)
{
descriptor.at<float>(i) = uStr2Float(*iter);
}
if(i != dimension)
{
UERROR("");
}
VisualWord * vw = new VisualWord(id, descriptor, 0);
_visualWords.insert(_visualWords.end(), std::pair<int, VisualWord*>(id, vw));
_notIndexedWords.insert(_notIndexedWords.end(), id);
}
else
{
UWARN("Cannot parse line \"%s\"", str.c_str());
}
}
this->update();
_incrementalDictionary = false;
UERROR("Could not load dictionary from database %s", dictionaryPath.c_str());
}
UDEBUG("Time changing dictionary = %fs", timer.ticks());
delete driver;
}
else
{
UERROR("Cannot open dictionary file \"%s\"", dictionaryPath.c_str());
UWARN("Loading fixed vocabulary \"%s\", this may take a while...", dictionaryPath.c_str());
std::ifstream file;
file.open(dictionaryPath.c_str(), std::ifstream::in);
if(file.good())
{
UDEBUG("Deleting old dictionary and loading the new one from \"%s\"", dictionaryPath.c_str());
UTimer timer;
// first line is the header
std::string str;
std::list<std::string> strList;
std::getline(file, str);
strList = uSplitNumChar(str);
int dimension = 0;
for(std::list<std::string>::iterator iter = strList.begin(); iter != strList.end(); ++iter)
{
if(uIsDigit(iter->at(0)))
{
dimension = std::atoi(iter->c_str());
break;
}
}
UDEBUG("descriptor dimension = %d", dimension);
if(dimension <= 0 || dimension > 1000)
{
UERROR("Invalid dictionary file, visual word dimension (%d) is not valid, \"%s\"", dimension, dictionaryPath.c_str());
}
else
{
// Process all words
while(file.good())
{
std::getline(file, str);
strList = uSplit(str);
if((int)strList.size() == dimension+1)
{
//first one is the visual word id
std::list<std::string>::iterator iter = strList.begin();
int id = std::atoi(iter->c_str());
cv::Mat descriptor(1, dimension, CV_32F);
++iter;
int i=0;
//get descriptor
for(;i<dimension && iter != strList.end(); ++i, ++iter)
{
descriptor.at<float>(i) = uStr2Float(*iter);
}
if(i != dimension)
{
UERROR("Loaded word has not the same size (%d) than descriptor size previously detected (%d).", i, dimension);
}
VisualWord * vw = new VisualWord(id, descriptor, 0);
_visualWords.insert(_visualWords.end(), std::pair<int, VisualWord*>(id, vw));
_notIndexedWords.insert(_notIndexedWords.end(), id);
_unusedWords.insert(_unusedWords.end(), std::pair<int, VisualWord*>(id, vw));
}
else if(!str.empty())
{
UWARN("Cannot parse line \"%s\"", str.c_str());
}
}
if(_visualWords.size())
{
UWARN("Loaded %d words!", (int)_visualWords.size());
}
}
}
else
{
UERROR("Cannot open dictionary file \"%s\"", dictionaryPath.c_str());
}
file.close();
}
if(_visualWords.size() == 0)
{
_incrementalDictionary = _visualWords.size()==0;
UWARN("No words loaded, cannot set a fixed dictionary.", (int)_visualWords.size());
}
else
{
this->update();
_incrementalDictionary = false;
UDEBUG("Loaded %d words!", (int)_visualWords.size());
}
file.close();
}
else if(!_incrementalDictionary)
{
@@ -225,14 +265,14 @@ void VWDictionary::setFixedDictionary(const std::string & dictionaryPath)
UERROR("Cannot change to a fixed dictionary if there are already words (%d) in the incremental one.", _visualWords.size());
}
}
else if(_visualWords.size() == 0)
{
_incrementalDictionary = false;
}
else if(_incrementalDictionary)
else if(_incrementalDictionary && _visualWords.size())
{
UWARN("Cannot change to fixed dictionary, %d words already loaded as incremental", (int)_visualWords.size());
}
else
{
_incrementalDictionary = false;
}
_dictionaryPath = dictionaryPath;
}
@@ -568,7 +608,7 @@ void VWDictionary::addWordRef(int wordId, int signatureId)
}
else
{
UERROR("Not found word %d", wordId);
UERROR("Not found word %d (dict size=%d)", wordId, (int)_visualWords.size());
}
}
}
@@ -1220,26 +1260,17 @@ VisualWord * VWDictionary::getUnusedWord(int id) const
std::vector<VisualWord*> VWDictionary::getUnusedWords() const
{
if(!_incrementalDictionary)
{
ULOGGER_WARN("This method does nothing on a fixed dictionary");
return std::vector<VisualWord*>();
}
return uValues(_unusedWords);
}
std::vector<int> VWDictionary::getUnusedWordIds() const
{
if(!_incrementalDictionary)
{
ULOGGER_WARN("This method does nothing on a fixed dictionary");
return std::vector<int>();
}
return uKeys(_unusedWords);
}
void VWDictionary::removeWords(const std::vector<VisualWord*> & words)
{
UDEBUG("Removing %d words from dictionary (current size=%d)", (int)words.size(), (int)_visualWords.size());
for(unsigned int i=0; i<words.size(); ++i)
{
_visualWords.erase(words[i]->id());

View File

@@ -18,7 +18,57 @@ RUN apt-get update && apt-get install -y \
WORKDIR /root/
# GTSAM
RUN git clone https://bitbucket.org/gtborg/gtsam.git
RUN cd gtsam && \
git checkout 4.0.0-alpha2 && \
mkdir build && \
cd build && \
cmake -DMETIS_SHARED=ON -DGTSAM_BUILD_STATIC_LIBRARY=OFF -DGTSAM_BUILD_TESTS=OFF -DGTSAM_BUILD_EXAMPLES_ALWAYS=OFF -DCMAKE_BUILD_TYPE=Release .. && \
make -j$(nproc) && \
make install && \
cd && \
rm -r gtsam
# g2o
RUN git clone https://github.com/RainerKuemmerle/g2o.git
RUN cd g2o && \
git checkout 20170730_git && \
mkdir build && \
cd build && \
cmake -DBUILD_LGPL_SHARED_LIBS=ON -DG2O_BUILD_APPS=OFF -DG2O_BUILD_EXAMPLES=OFF -DBUILD_SHARED_LIBS=ON -DCMAKE_BUILD_TYPE=Release .. && \
make -j$(nproc) && \
make install && \
cd && \
rm -r g2o
# libpointmatcher
RUN git clone https://github.com/ethz-asl/libnabo.git
#commit Apr 25 2018
RUN cd libnabo && \
git checkout 7e378f6765393462357b8b74d8dc8c5554542ae6 && \
mkdir build && \
cd build && \
cmake -DCMAKE_BUILD_TYPE=Release .. && \
make -j$(nproc) && \
make install && \
cd && \
rm -r libnabo
RUN git clone https://github.com/ethz-asl/libpointmatcher.git
#commit Jan 19 2018
RUN cd libpointmatcher && \
git checkout 00004bd41e44a1cf8de24ad87e4914760717cbcc && \
mkdir build && \
cd build && \
cmake -DCMAKE_BUILD_TYPE=Release .. && \
make -j$(nproc) && \
make install && \
cd && \
rm -r libpointmatcher
# Clone source code
ARG CACHE_DATE=2016-01-01
RUN git clone https://github.com/introlab/rtabmap.git
# Build RTAB-Map project

View File

@@ -0,0 +1,2 @@
#!/bin/bash
docker build --build-arg CACHE_DATE="$(date)" --cache-from $IMAGE_NAME -f $DOCKERFILE_PATH -t $IMAGE_NAME -t $DOCKER_REPO:17.10 .

View File

@@ -0,0 +1,2 @@
#!/bin/bash
docker push $DOCKER_REPO:17.10

View File

@@ -18,7 +18,57 @@ RUN apt-get update && DEBIAN_FRONTEND=noninteractive apt-get install -y \
WORKDIR /root/
# GTSAM
RUN git clone https://bitbucket.org/gtborg/gtsam.git
RUN cd gtsam && \
git checkout 4.0.0-alpha2 && \
mkdir build && \
cd build && \
cmake -DMETIS_SHARED=ON -DGTSAM_BUILD_STATIC_LIBRARY=OFF -DGTSAM_BUILD_TESTS=OFF -DGTSAM_BUILD_EXAMPLES_ALWAYS=OFF -DCMAKE_BUILD_TYPE=Release .. && \
make -j$(nproc) && \
make install && \
cd && \
rm -r gtsam
# g2o
RUN git clone https://github.com/RainerKuemmerle/g2o.git
RUN cd g2o && \
git checkout 20170730_git && \
mkdir build && \
cd build && \
cmake -DBUILD_LGPL_SHARED_LIBS=ON -DG2O_BUILD_APPS=OFF -DG2O_BUILD_EXAMPLES=OFF -DBUILD_SHARED_LIBS=ON -DCMAKE_BUILD_TYPE=Release .. && \
make -j$(nproc) && \
make install && \
cd && \
rm -r g2o
# libpointmatcher
RUN git clone https://github.com/ethz-asl/libnabo.git
#commit Apr 25 2018
RUN cd libnabo && \
git checkout 7e378f6765393462357b8b74d8dc8c5554542ae6 && \
mkdir build && \
cd build && \
cmake -DCMAKE_BUILD_TYPE=Release .. && \
make -j$(nproc) && \
make install && \
cd && \
rm -r libnabo
RUN git clone https://github.com/ethz-asl/libpointmatcher.git
#commit Jan 19 2018
RUN cd libpointmatcher && \
git checkout 00004bd41e44a1cf8de24ad87e4914760717cbcc && \
mkdir build && \
cd build && \
cmake -DCMAKE_BUILD_TYPE=Release .. && \
make -j$(nproc) && \
make install && \
cd && \
rm -r libpointmatcher
# Clone source code
ARG CACHE_DATE=2016-01-01
RUN git clone https://github.com/introlab/rtabmap.git
# Build RTAB-Map project

View File

@@ -0,0 +1,2 @@
#!/bin/bash
docker build --build-arg CACHE_DATE="$(date)" --cache-from $IMAGE_NAME -f $DOCKERFILE_PATH -t $IMAGE_NAME -t $DOCKER_REPO:18.04 .

View File

@@ -0,0 +1,2 @@
#!/bin/bash
docker push $DOCKER_REPO:18.04

View File

@@ -15,8 +15,58 @@ RUN apt-get update && apt-get install -y \
libopenni2-dev \
software-properties-common
# Clone source code
WORKDIR /root/
# GTSAM
RUN git clone https://bitbucket.org/gtborg/gtsam.git
RUN cd gtsam && \
git checkout 4.0.0-alpha2 && \
mkdir build && \
cd build && \
cmake -DMETIS_SHARED=ON -DGTSAM_BUILD_STATIC_LIBRARY=OFF -DGTSAM_BUILD_TESTS=OFF -DGTSAM_BUILD_EXAMPLES_ALWAYS=OFF -DCMAKE_BUILD_TYPE=Release .. && \
make -j$(nproc) && \
make install && \
cd && \
rm -r gtsam
# g2o
RUN git clone https://github.com/RainerKuemmerle/g2o.git
RUN cd g2o && \
git checkout 20170730_git && \
mkdir build && \
cd build && \
cmake -DBUILD_LGPL_SHARED_LIBS=ON -DG2O_BUILD_APPS=OFF -DG2O_BUILD_EXAMPLES=OFF -DBUILD_SHARED_LIBS=ON -DCMAKE_BUILD_TYPE=Release .. && \
make -j$(nproc) && \
make install && \
cd && \
rm -r g2o
# libpointmatcher
RUN git clone https://github.com/ethz-asl/libnabo.git
#commit Apr 25 2018
RUN cd libnabo && \
git checkout 7e378f6765393462357b8b74d8dc8c5554542ae6 && \
mkdir build && \
cd build && \
cmake -DCMAKE_BUILD_TYPE=Release .. && \
make -j$(nproc) && \
make install && \
cd && \
rm -r libnabo
RUN git clone https://github.com/ethz-asl/libpointmatcher.git
#commit Jan 19 2018
RUN cd libpointmatcher && \
git checkout 00004bd41e44a1cf8de24ad87e4914760717cbcc && \
mkdir build && \
cd build && \
cmake -DCMAKE_BUILD_TYPE=Release .. && \
make -j$(nproc) && \
make install && \
cd && \
rm -r libpointmatcher
# Clone source code
ARG CACHE_DATE=2016-01-01
RUN git clone https://github.com/introlab/rtabmap.git
# Build RTAB-Map project

37
docker/xenial/android/install_deps.bash Normal file → Executable file
View File

@@ -29,7 +29,7 @@ rm -r *
cmake -DCMAKE_TOOLCHAIN_FILE=$pwd/android.toolchain.cmake -DANDROID_ABI=arm64-v8a -DBUILD_SHARED_LIBS=OFF -DCMAKE_BUILD_TYPE=Release -DCMAKE_INSTALL_PREFIX=$prefix/arm64-v8a ..
make
make install
cd
cd $pwd
rm -r boost_1_59_0.tar.gz boost_1_59_0
# eigen
@@ -46,7 +46,7 @@ rm -r *
cmake -DCMAKE_TOOLCHAIN_FILE=$pwd/android.toolchain.cmake -DANDROID_ABI=arm64-v8a -DBUILD_SHARED_LIBS=OFF -DCMAKE_BUILD_TYPE=Release -DCMAKE_INSTALL_PREFIX=$prefix/arm64-v8a ..
make
make install
cd
cd $pwd
rm -r 3.2.7.tar.gz eigen-eigen-b30b87236a1b
# FLANN
@@ -63,7 +63,7 @@ rm -r *
cmake -DCMAKE_TOOLCHAIN_FILE=$pwd/android.toolchain.cmake -DANDROID_ABI=arm64-v8a -DBUILD_SHARED_LIBS=OFF -DCMAKE_BUILD_TYPE=Release -DCMAKE_INSTALL_PREFIX=$prefix/arm64-v8a ..
make
make install
cd
cd $pwd
rm -r flann-1.8.4-src.zip flann-1.8.4-src
# GTSAM
@@ -82,12 +82,13 @@ rm -r *
cmake -DCMAKE_TOOLCHAIN_FILE=$pwd/android.toolchain.cmake -DANDROID_ABI=arm64-v8a -DMETIS_SHARED=OFF -DGTSAM_BUILD_STATIC_LIBRARY=ON -DGTSAM_BUILD_TESTS=OFF -DGTSAM_BUILD_EXAMPLES_ALWAYS=OFF -DCMAKE_BUILD_TYPE=Release -DCMAKE_INSTALL_PREFIX=$prefix/arm64-v8a ..
make
make install
cd
rm -r gtsam
cd $pwd
rm -rf gtsam
# g2o
git clone https://github.com/RainerKuemmerle/g2o.git
cd g2o
git checkout a3f7706bdbb849b2808dc3e1b7aee189f63b498e
mkdir build
cd build
cmake -DCMAKE_TOOLCHAIN_FILE=$pwd/android.toolchain.cmake -DANDROID_ABI=armeabi-v7a -DBUILD_LGPL_SHARED_LIBS=OFF -DG2O_BUILD_APPS=OFF -DG2O_BUILD_EXAMPLES=OFF -DBUILD_SHARED_LIBS=OFF -DCMAKE_BUILD_TYPE=Release -DCMAKE_INSTALL_PREFIX=$prefix/armeabi-v7a ..
@@ -97,8 +98,8 @@ rm -r *
cmake -DCMAKE_TOOLCHAIN_FILE=$pwd/android.toolchain.cmake -DANDROID_ABI=arm64-v8a -DBUILD_LGPL_SHARED_LIBS=OFF -DG2O_BUILD_APPS=OFF -DG2O_BUILD_EXAMPLES=OFF -DBUILD_SHARED_LIBS=OFF -DCMAKE_BUILD_TYPE=Release -DCMAKE_INSTALL_PREFIX=$prefix/arm64-v8a ..
make
make install
cd
rm -r g2o
cd $pwd
rm -rf g2o
#CMake 3.7 for VTK
@@ -113,15 +114,15 @@ cd VTK
git checkout tags/v7.1.1
mkdir build
cd build
~/cmake-3.7.2-Linux-x86_64/bin/cmake -DBUILD_EXAMPLES=OFF -DBUILD_TESTING=OFF -DVTK_ANDROID_BUILD=ON -DANDROID_ARCH_ABI=armeabi-v7a -DBUILD_SHARED_LIBS=OFF -DCMAKE_BUILD_TYPE=Release -DCMAKE_INSTALL_PREFIX=$prefix/armeabi-v7a ..
$pwd/cmake-3.7.2-Linux-x86_64/bin/cmake -DBUILD_EXAMPLES=OFF -DBUILD_TESTING=OFF -DVTK_ANDROID_BUILD=ON -DANDROID_ARCH_ABI=armeabi-v7a -DBUILD_SHARED_LIBS=OFF -DCMAKE_BUILD_TYPE=Release -DCMAKE_INSTALL_PREFIX=$prefix/armeabi-v7a ..
make
cp -r CMakeExternals/Install/vtk-android/* $prefix/armeabi-v7a/.
rm -r *
~/cmake-3.7.2-Linux-x86_64/bin/cmake -DBUILD_EXAMPLES=OFF -DBUILD_TESTING=OFF -DVTK_ANDROID_BUILD=ON -DANDROID_ARCH_ABI=arm64-v8a -DBUILD_SHARED_LIBS=OFF -DCMAKE_BUILD_TYPE=Release -DCMAKE_INSTALL_PREFIX=$prefix/arm64-v8a ..
$pwd/cmake-3.7.2-Linux-x86_64/bin/cmake -DBUILD_EXAMPLES=OFF -DBUILD_TESTING=OFF -DVTK_ANDROID_BUILD=ON -DANDROID_ARCH_ABI=arm64-v8a -DBUILD_SHARED_LIBS=OFF -DCMAKE_BUILD_TYPE=Release -DCMAKE_INSTALL_PREFIX=$prefix/arm64-v8a ..
make
cp -r CMakeExternals/Install/vtk-android/* $prefix/arm64-v8a/.
cd
rm -r VTK cmake-3.7.2-Linux-x86_64
cd $pwd
rm -rf VTK cmake-3.7.2-Linux-x86_64
# PCL
git clone https://github.com/PointCloudLibrary/pcl.git
@@ -143,25 +144,25 @@ cmake -DCMAKE_TOOLCHAIN_FILE=$pwd/android.toolchain.cmake -DANDROID_ABI=arm64-v8
cmake -DCMAKE_TOOLCHAIN_FILE=$pwd/android.toolchain.cmake -DANDROID_ABI=arm64-v8a -DBUILD_apps=OFF -DBUILD_examples=OFF -DBUILD_tools=OFF -DBUILD_visualization=OFF -DBUILD_tracking=OFF -DBUILD_people=OFF -DBUILD_global_tests=OFF -DWITH_QT=OFF -DWITH_OPENGL=OFF -DWITH_VTK=ON -DPCL_SHARED_LIBS=OFF -DCMAKE_BUILD_TYPE=Release -DCMAKE_INSTALL_PREFIX=$prefix/arm64-v8a ..
make
make install
cd
rm -r pcl
cd $pwd
rm -rf pcl
# OpenCV
git clone https://github.com/opencv/opencv_contrib.git
cd opencv_contrib
git checkout tags/3.2.0
cd
cd $pwd
git clone https://github.com/opencv/opencv.git
cd opencv
git checkout tags/3.2.0
mkdir build
cd build
cmake -DCMAKE_TOOLCHAIN_FILE=$pwd/android.toolchain.cmake -DANDROID_ABI=armeabi-v7a -DOPENCV_EXTRA_MODULES_PATH=$pwd/opencv_contrib/modules -DCMAKE_BUILD_TYPE=Release -DBUILD_SHARED_LIBS=OFF -DBUILD_TESTS=OFF -DBUILD_PERF_TESTS=OFF -DCMAKE_INSTALL_PREFIX=$prefix/armeabi-v7a ..
cmake -DCMAKE_TOOLCHAIN_FILE=$pwd/android.toolchain.cmake -DANDROID_ABI=armeabi-v7a -DOPENCV_EXTRA_MODULES_PATH=$pwd/opencv_contrib/modules -DCMAKE_BUILD_TYPE=Release -DBUILD_SHARED_LIBS=OFF -DBUILD_TESTS=OFF -DBUILD_PERF_TESTS=OFF -DWITH_CUDA=OFF -DCMAKE_INSTALL_PREFIX=$prefix/armeabi-v7a ..
make
make install
rm -r *
cmake -DCMAKE_TOOLCHAIN_FILE=$pwd/android.toolchain.cmake -DANDROID_ABI=arm64-v8a -DOPENCV_EXTRA_MODULES_PATH=$pwd/opencv_contrib/modules -DCMAKE_BUILD_TYPE=Release -DBUILD_SHARED_LIBS=OFF -DBUILD_TESTS=OFF -DBUILD_PERF_TESTS=OFF -DCMAKE_INSTALL_PREFIX=$prefix/arm64-v8a ..
cmake -DCMAKE_TOOLCHAIN_FILE=$pwd/android.toolchain.cmake -DANDROID_ABI=arm64-v8a -DOPENCV_EXTRA_MODULES_PATH=$pwd/opencv_contrib/modules -DCMAKE_BUILD_TYPE=Release -DBUILD_SHARED_LIBS=OFF -DBUILD_TESTS=OFF -DBUILD_PERF_TESTS=OFF -DWITH_CUDA=OFF -DCMAKE_INSTALL_PREFIX=$prefix/arm64-v8a ..
make
make install
cd
rm -r opencv opencv_contrib
cd $pwd
rm -rf opencv opencv_contrib

View File

@@ -5,8 +5,8 @@ if [ $# -ne 1 ]; then
exit 1
fi
apt-get update
apt-get install -y git cmake g++ software-properties-common wget unzip zlib1g-dev qtbase5-dev libqt5x11extras5-dev libqt5svg5-dev qttools5-dev libxt-dev
sudo apt-get update
sudo apt-get install -y git cmake g++ software-properties-common wget unzip zlib1g-dev qtbase5-dev libqt5x11extras5-dev libqt5svg5-dev qttools5-dev libxt-dev
prefix=$1
pwd=$(pwd)
@@ -25,7 +25,7 @@ cd build
cmake -DBUILD_SHARED_LIBS=ON -DCMAKE_BUILD_TYPE=Release -DCMAKE_INSTALL_PREFIX=$prefix ..
make
make install
cd
cd $pwd
rm -r boost_1_59_0.tar.gz boost_1_59_0
# eigen
@@ -38,7 +38,7 @@ cd build
cmake -DBUILD_SHARED_LIBS=ON -DCMAKE_BUILD_TYPE=Release -DCMAKE_INSTALL_PREFIX=$prefix ..
make
make install
cd
cd $pwd
rm -r 3.2.7.tar.gz eigen-eigen-b30b87236a1b
# FLANN
@@ -51,7 +51,7 @@ cd build
cmake -DBUILD_SHARED_LIBS=ON -DCMAKE_BUILD_TYPE=Release -DCMAKE_INSTALL_PREFIX=$prefix ..
make
make install
cd
cd $pwd
rm -r flann-1.8.4-src.zip flann-1.8.4-src
# GTSAM
@@ -66,19 +66,20 @@ cd build
cmake -DMETIS_SHARED=ON -DGTSAM_BUILD_STATIC_LIBRARY=OFF -DGTSAM_BUILD_TESTS=OFF -DGTSAM_BUILD_EXAMPLES_ALWAYS=OFF -DCMAKE_BUILD_TYPE=Release -DCMAKE_INSTALL_PREFIX=$prefix ..
make
make install
cd
rm -r gtsam
cd $pwd
rm -rf gtsam
# g2o
git clone https://github.com/RainerKuemmerle/g2o.git
cd g2o
git checkout a3f7706bdbb849b2808dc3e1b7aee189f63b498e
mkdir build
cd build
cmake -DBUILD_LGPL_SHARED_LIBS=ON -DG2O_BUILD_APPS=OFF -DG2O_BUILD_EXAMPLES=OFF -DBUILD_SHARED_LIBS=ON -DCMAKE_BUILD_TYPE=Release -DCMAKE_INSTALL_PREFIX=$prefix ..
make
make install
cd
rm -r g2o
cd $pwd
rm -rf g2o
# VTK
git clone https://github.com/Kitware/VTK.git
@@ -89,8 +90,8 @@ cd build
cmake -DBUILD_EXAMPLES=OFF -DBUILD_TESTING=OFF -DBUILD_SHARED_LIBS=ON -DCMAKE_BUILD_TYPE=Release -DVTK_Group_Qt=ON -DVTK_QT_VERSION=5 -DCMAKE_INSTALL_PREFIX=$prefix ..
make
make install
cd
rm -r VTK
cd $pwd
rm -rf VTK
# PCL
git clone https://github.com/PointCloudLibrary/pcl.git
@@ -104,14 +105,14 @@ cd build
cmake -DBUILD_apps=OFF -DBUILD_examples=OFF -DBUILD_tools=OFF -DBUILD_visualization=ON -DBUILD_tracking=OFF -DBUILD_people=OFF -DBUILD_global_tests=OFF -DWITH_QT=ON -DWITH_OPENGL=OFF -DWITH_VTK=ON -DPCL_SHARED_LIBS=ON -DCMAKE_BUILD_TYPE=Release -DCMAKE_INSTALL_PREFIX=$prefix ..
make
make install
cd
rm -r pcl
cd $pwd
rm -rf pcl
# OpenCV
git clone https://github.com/opencv/opencv_contrib.git
cd opencv_contrib
git checkout tags/3.2.0
cd
cd $pwd
git clone https://github.com/opencv/opencv.git
cd opencv
git checkout tags/3.2.0
@@ -120,5 +121,5 @@ cd build
cmake -DOPENCV_EXTRA_MODULES_PATH=$pwd/opencv_contrib/modules -DCMAKE_BUILD_TYPE=Release -DBUILD_SHARED_LIBS=ON -DBUILD_TESTS=OFF -DBUILD_PERF_TESTS=OFF -DCMAKE_INSTALL_PREFIX=$prefix ..
make
make install
cd
rm -r opencv opencv_contrib
cd $pwd
rm -rf opencv opencv_contrib

View File

@@ -35,7 +35,7 @@ mv TangoSDK_Ikariotikos_Java.jar rtabmap-tango/app/android/libs/.
cd rtabmap-tango/build
cmake -DANDROID_PREBUILD=ON ..
make
cd
cd ../..
# rtabmap
mkdir rtabmap-tango/build/armeabi-v7a
@@ -43,7 +43,7 @@ cd rtabmap-tango/build/armeabi-v7a
cmake -DCMAKE_TOOLCHAIN_FILE=../../cmake_modules/android.toolchain.cmake -DANDROID_ABI=armeabi-v7a -DBUILD_SHARED_LIBS=OFF -DBUILD_EXAMPLES=OFF -DBUILD_TOOLS=OFF -DCMAKE_BUILD_TYPE=Release -DOpenCV_DIR=$prefix/armeabi-v7a/sdk/native/jni -DCMAKE_INSTALL_PREFIX=$prefix/armeabi-v7a ../..
make
cd
cd ../../..
mkdir rtabmap-tango/build/arm64-v8a
cd rtabmap-tango/build/arm64-v8a
cmake -DCMAKE_TOOLCHAIN_FILE=../../cmake_modules/android.toolchain.cmake -DANDROID_ABI=arm64-v8a -DBUILD_SHARED_LIBS=OFF -DBUILD_EXAMPLES=OFF -DBUILD_TOOLS=OFF -DCMAKE_BUILD_TYPE=Release -DOpenCV_DIR=$prefix/arm64-v8a/sdk/native/jni -DCMAKE_INSTALL_PREFIX=$prefix/arm64-v8a ../..

View File

@@ -0,0 +1,2 @@
#!/bin/bash
docker build --build-arg CACHE_DATE="$(date)" --cache-from $IMAGE_NAME -f $DOCKERFILE_PATH -t $IMAGE_NAME -t $DOCKER_REPO:16.04 -t $DOCKER_REPO:latest .

View File

@@ -0,0 +1,3 @@
#!/bin/bash
docker push $DOCKER_REPO:16.04
docker push $DOCKER_REPO:latest

View File

@@ -16,8 +16,59 @@ RUN apt-get update && apt-get install -y \
# Issue: http://www.pcl-users.org/Build-failure-on-Ubuntu-17-04-td4044552.html
RUN sed -i 's|/usr/lib/libmpi.so;||g' /usr/lib/x86_64-linux-gnu/cmake/pcl/PCLConfig.cmake
# Clone source code
WORKDIR /root/
# GTSAM
RUN git clone https://bitbucket.org/gtborg/gtsam.git
RUN cd gtsam && \
git checkout 4.0.0-alpha2 && \
mkdir build && \
cd build && \
cmake -DMETIS_SHARED=ON -DGTSAM_BUILD_STATIC_LIBRARY=OFF -DGTSAM_BUILD_TESTS=OFF -DGTSAM_BUILD_EXAMPLES_ALWAYS=OFF -DCMAKE_BUILD_TYPE=Release .. && \
make -j$(nproc) && \
make install && \
cd && \
rm -r gtsam
# g2o
RUN git clone https://github.com/RainerKuemmerle/g2o.git
RUN cd g2o && \
git checkout 20170730_git && \
mkdir build && \
cd build && \
cmake -DBUILD_LGPL_SHARED_LIBS=ON -DG2O_BUILD_APPS=OFF -DG2O_BUILD_EXAMPLES=OFF -DBUILD_SHARED_LIBS=ON -DCMAKE_BUILD_TYPE=Release .. && \
make -j$(nproc) && \
make install && \
cd && \
rm -r g2o
# libpointmatcher
RUN git clone https://github.com/ethz-asl/libnabo.git
#commit Apr 25 2018
RUN cd libnabo && \
git checkout 7e378f6765393462357b8b74d8dc8c5554542ae6 && \
mkdir build && \
cd build && \
cmake -DCMAKE_BUILD_TYPE=Release .. && \
make -j$(nproc) && \
make install && \
cd && \
rm -r libnabo
RUN git clone https://github.com/ethz-asl/libpointmatcher.git
#commit Jan 19 2018
RUN cd libpointmatcher && \
git checkout 00004bd41e44a1cf8de24ad87e4914760717cbcc && \
mkdir build && \
cd build && \
cmake -DCMAKE_BUILD_TYPE=Release .. && \
make -j$(nproc) && \
make install && \
cd && \
rm -r libpointmatcher
# Clone source code
ARG CACHE_DATE=2016-01-01
RUN git clone https://github.com/introlab/rtabmap.git
# Build RTAB-Map project

2
docker/zesty/hooks/build Normal file
View File

@@ -0,0 +1,2 @@
#!/bin/bash
docker build --build-arg CACHE_DATE="$(date)" --cache-from $IMAGE_NAME -f $DOCKERFILE_PATH -t $IMAGE_NAME -t $DOCKER_REPO:17.04 .

View File

@@ -0,0 +1,2 @@
#!/bin/bash
docker push $DOCKER_REPO:17.04

View File

@@ -38,6 +38,7 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include "rtabmap/core/util3d_filtering.h"
#include "rtabmap/core/util3d_transforms.h"
#include "rtabmap/core/RtabmapEvent.h"
#include "rtabmap/core/OccupancyGrid.h"
#endif
#include "rtabmap/utilite/UStl.h"
#include "rtabmap/utilite/UConversion.h"
@@ -242,6 +243,44 @@ protected slots:
cloudViewer_->setCloudPointSize("graph_nodes", 5);
}
//============================
// Update/add occupancy grid (when RGBD/CreateOccupancyGrid is true)
//============================
for(std::map<int, Transform>::const_reverse_iterator iter = stats.poses().rbegin(); iter!=stats.poses().rend(); ++iter)
{
int id = iter->first;
if(grid_.addedNodes().find(id) == grid_.addedNodes().end())
{
std::map<int, Signature>::const_iterator jter = stats.getSignatures().find(id);
if(jter != stats.getSignatures().end() && jter->second.sensorData().gridCellSize() > 0.0f)
{
cv::Mat groundCells, obstacleCells, emptyCells;
jter->second.sensorData().uncompressDataConst(0, 0, 0, 0, &groundCells, &obstacleCells, &emptyCells);
grid_.addToCache(id, groundCells, obstacleCells, emptyCells);
}
}
else
{
// Assume that older nodes are already added to map
break;
}
}
if(grid_.addedNodes().size() || grid_.cacheSize())
{
grid_.update(stats.poses());
}
if(grid_.addedNodes().size())
{
float xMin, yMin;
cv::Mat map8S = grid_.getMap(xMin, yMin);
if(!map8S.empty())
{
//convert to gray scaled map
cv::Mat map8U = util3d::convertMap2Image8U(map8S);
cloudViewer_->addOccupancyGridMap(map8U, grid_.getCellSize(), xMin, yMin, 0.75);
}
}
odometryCorrection_ = stats.mapCorrection();
cloudViewer_->update();
@@ -283,6 +322,7 @@ protected:
Transform odometryCorrection_;
bool processingStatistics_;
bool lastOdometryProcessed_;
OccupancyGrid grid_;
};

View File

@@ -163,9 +163,12 @@ int main(int argc, char * argv[])
OdometryThread odomThread(new OdometryF2M());
ParametersMap params;
//param.insert(ParametersPair(Parameters::kRGBDCreateOccupancyGrid(), "true")); // uncomment to create local occupancy grids
// Create RTAB-Map to process OdometryEvent
Rtabmap * rtabmap = new Rtabmap();
rtabmap->init();
rtabmap->init(params);
RtabmapThread rtabmapThread(rtabmap); // ownership is transfered
// Setup handlers

View File

@@ -2067,7 +2067,7 @@ void MainWindow::updateMapCloud(
{
std::map<int, Transform> posesInTmp = posesIn;
posesInTmp.erase(-1);
poses = rtabmap::graph::radiusPosesFiltering(posesIn, radius, angle);
poses = rtabmap::graph::radiusPosesFiltering(posesInTmp, radius, angle);
}
else
{

View File

@@ -4171,11 +4171,11 @@ void PreferencesDialog::changeDictionaryPath()
QString path;
if(_ui->lineEdit_dictionaryPath->text().isEmpty())
{
path = QFileDialog::getOpenFileName(this, tr("Dictionary"), this->getWorkingDirectory());
path = QFileDialog::getOpenFileName(this, tr("Dictionary"), this->getWorkingDirectory(), tr("Dictionary (*.txt *.db)"));
}
else
{
path = QFileDialog::getOpenFileName(this, tr("Dictionary"), _ui->lineEdit_dictionaryPath->text());
path = QFileDialog::getOpenFileName(this, tr("Dictionary"), _ui->lineEdit_dictionaryPath->text(), tr("Dictionary (*.txt *.db)"));
}
if(!path.isEmpty())
{
@@ -4188,11 +4188,11 @@ void PreferencesDialog::changeOdometryORBSLAM2Vocabulary()
QString path;
if(_ui->lineEdit_OdomORBSLAM2VocPath->text().isEmpty())
{
path = QFileDialog::getOpenFileName(this, tr("ORBSLAM2 Vocabulary"), this->getWorkingDirectory());
path = QFileDialog::getOpenFileName(this, tr("ORBSLAM2 Vocabulary"), this->getWorkingDirectory(), tr("Vocabulary (*.txt)"));
}
else
{
path = QFileDialog::getOpenFileName(this, tr("ORBSLAM2 Vocabulary"), _ui->lineEdit_OdomORBSLAM2VocPath->text());
path = QFileDialog::getOpenFileName(this, tr("ORBSLAM2 Vocabulary"), _ui->lineEdit_OdomORBSLAM2VocPath->text(), tr("Vocabulary (*.txt)"));
}
if(!path.isEmpty())
{

View File

@@ -1,7 +1,7 @@
<?xml version="1.0"?>
<package>
<name>rtabmap</name>
<version>0.17.0</version>
<version>0.17.1</version>
<description>RTAB-Map's standalone library. RTAB-Map is a RGB-D SLAM approach with real-time constraints.</description>
<maintainer email="matlabbe@gmail.com">Mathieu Labbe</maintainer>
<author>Mathieu Labbe</author>

View File

@@ -43,7 +43,13 @@ void showUsage()
{
printf("\nUsage:\n"
"rtabmap-report [\"Statistic/Id\"] [--latex] [--kitti] [--scale] [--poses] path\n"
" path Directory containing rtabmap databases or path of a database.\n\n");
" path Directory containing rtabmap databases or path of a database.\n"
" --latex Print table formatted in LaTeX with results.\n"
" --kitti Compute error based on KITTI benchmark.\n"
" --scale Find the best scale for the map against the ground truth\n"
" and compute error based on the scaled path.\n"
" --poses Export poses to [path]_poses.txt, ground truth to [path]_gt.txt\n"
" and valid ground truth indices to [path]_indices.txt \n\n");
exit(1);
}
@@ -54,6 +60,9 @@ int main(int argc, char * argv[])
showUsage();
}
ULogger::setType(ULogger::kTypeConsole);
ULogger::setLevel(ULogger::kWarning);
QApplication app(argc, argv);
bool outputLatex = false;
@@ -161,7 +170,9 @@ int main(int argc, char * argv[])
ParametersMap params;
if(driver->openConnection(filePath))
{
ULogger::setLevel(ULogger::kError); // to suppress parameter warnings
params = driver->getLastParameters();
ULogger::setLevel(ULogger::kWarning);
std::set<int> ids;
driver->getAllNodeIds(ids);
std::map<int, std::pair<std::map<std::string, float>, double> > stats = driver->getAllStatistics();
@@ -294,114 +305,162 @@ int main(int argc, char * argv[])
optimizer->getConnectedGraph(firstId, odomPoses, graph::filterDuplicateLinks(links), posesOut, linksOut);
std::map<int, Transform> poses = optimizer->optimize(firstId, posesOut, linksOut);
std::map<int, Transform> groundTruth;
for(std::map<int, Transform>::const_iterator iter=poses.begin(); iter!=poses.end(); ++iter)
if(poses.empty())
{
if(gtPoses.find(iter->first) != gtPoses.end())
// try incremental optimization
UWARN("Optimization failed! Try incremental optimization...");
poses = optimizer->optimizeIncremental(firstId, posesOut, linksOut);
if(poses.empty())
{
groundTruth.insert(*gtPoses.find(iter->first));
}
}
for(float scale=outputScaled?0.900f:1.0f; scale<1.100f; scale+=0.001)
{
std::map<int, Transform> scaledPoses;
for(std::map<int, Transform>::iterator iter=poses.begin(); iter!=poses.end(); ++iter)
{
Transform t = iter->second.clone();
t.x() *= scale;
t.y() *= scale;
t.z() *= scale;
scaledPoses.insert(std::make_pair(iter->first, t));
}
// compute RMSE statistics
float translational_rmse = 0.0f;
float translational_mean = 0.0f;
float translational_median = 0.0f;
float translational_std = 0.0f;
float translational_min = 0.0f;
float translational_max = 0.0f;
float rotational_rmse = 0.0f;
float rotational_mean = 0.0f;
float rotational_median = 0.0f;
float rotational_std = 0.0f;
float rotational_min = 0.0f;
float rotational_max = 0.0f;
Transform gtToMap = graph::calcRMSE(
groundTruth,
scaledPoses,
translational_rmse,
translational_mean,
translational_median,
translational_std,
translational_min,
translational_max,
rotational_rmse,
rotational_mean,
rotational_median,
rotational_std,
rotational_min,
rotational_max);
if(bestRMSE!=-1 && translational_rmse > bestRMSE)
{
break;
}
bestRMSE = translational_rmse;
bestRMSEAng = rotational_rmse;
bestScale = scale;
bestGtToMap = gtToMap;
if(!outputScaled)
{
// just did iteration without any scale, then exit
break;
}
}
for(std::map<int, Transform>::iterator iter=poses.begin(); iter!=poses.end(); ++iter)
{
iter->second.x()*=bestScale;
iter->second.y()*=bestScale;
iter->second.z()*=bestScale;
iter->second = bestGtToMap * iter->second;
}
if(outputKittiError)
{
if(groundTruth.size() == poses.size())
{
// compute KITTI statistics
graph::calcKittiSequenceErrors(uValues(groundTruth), uValues(poses), kitti_t_err, kitti_r_err);
UERROR("Incremental optimization also failed! Only original RMSE will be shown.");
bestRMSE = rmse;
}
else
{
printf("Cannot compute KITTI statistics as optimized poses and ground truth don't have the same size (%d vs %d).\n",
(int)poses.size(), (int)groundTruth.size());
UWARN("Incremental optimization succeeded!");
}
}
if(outputPoses)
if(poses.size())
{
std::string dir = UDirectory::getDir(filePath);
std::string dbName = UFile::getName(filePath);
dbName = dbName.substr(0, dbName.size()-3); // remove db
std::string path = dir+UDirectory::separator()+dbName+"_poses.txt";
if(!graph::exportPoses(path, outputKittiError?2:0, poses))
std::map<int, Transform> groundTruth;
for(std::map<int, Transform>::const_iterator iter=poses.begin(); iter!=poses.end(); ++iter)
{
printf("Could not export the poses to \"%s\"!?!\n", path.c_str());
}
if(groundTruth.size())
{
path = dir+UDirectory::separator()+dbName+"_gt.txt";
if(!graph::exportPoses(path, outputKittiError?2:0, groundTruth))
if(gtPoses.find(iter->first) != gtPoses.end())
{
printf("Could not export the ground truth to \"%s\"!?!\n", path.c_str());
groundTruth.insert(*gtPoses.find(iter->first));
}
}
for(float scale=outputScaled?0.900f:1.0f; scale<1.100f; scale+=0.001)
{
std::map<int, Transform> scaledPoses;
for(std::map<int, Transform>::iterator iter=poses.begin(); iter!=poses.end(); ++iter)
{
Transform t = iter->second.clone();
t.x() *= scale;
t.y() *= scale;
t.z() *= scale;
scaledPoses.insert(std::make_pair(iter->first, t));
}
// compute RMSE statistics
float translational_rmse = 0.0f;
float translational_mean = 0.0f;
float translational_median = 0.0f;
float translational_std = 0.0f;
float translational_min = 0.0f;
float translational_max = 0.0f;
float rotational_rmse = 0.0f;
float rotational_mean = 0.0f;
float rotational_median = 0.0f;
float rotational_std = 0.0f;
float rotational_min = 0.0f;
float rotational_max = 0.0f;
Transform gtToMap = graph::calcRMSE(
groundTruth,
scaledPoses,
translational_rmse,
translational_mean,
translational_median,
translational_std,
translational_min,
translational_max,
rotational_rmse,
rotational_mean,
rotational_median,
rotational_std,
rotational_min,
rotational_max);
if(bestRMSE!=-1 && translational_rmse > bestRMSE)
{
break;
}
bestRMSE = translational_rmse;
bestRMSEAng = rotational_rmse;
bestScale = scale;
bestGtToMap = gtToMap;
if(!outputScaled)
{
// just did iteration without any scale, then exit
break;
}
}
for(std::map<int, Transform>::iterator iter=poses.begin(); iter!=poses.end(); ++iter)
{
iter->second.x()*=bestScale;
iter->second.y()*=bestScale;
iter->second.z()*=bestScale;
iter->second = bestGtToMap * iter->second;
}
if(outputKittiError)
{
if(groundTruth.size() == poses.size())
{
// compute KITTI statistics
graph::calcKittiSequenceErrors(uValues(groundTruth), uValues(poses), kitti_t_err, kitti_r_err);
}
else
{
printf("Cannot compute KITTI statistics as optimized poses and ground truth don't have the same size (%d vs %d).\n",
(int)poses.size(), (int)groundTruth.size());
}
}
if(outputPoses)
{
std::string dir = UDirectory::getDir(filePath);
std::string dbName = UFile::getName(filePath);
dbName = dbName.substr(0, dbName.size()-3); // remove db
std::string path = dir+UDirectory::separator()+dbName+"_poses.txt";
if(!graph::exportPoses(path, outputKittiError?2:0, poses))
{
printf("Could not export the poses to \"%s\"!?!\n", path.c_str());
}
if(groundTruth.size())
{
// For missing ground truth poses, set them to null
std::vector<int> validIndices(poses.size(), 1);
int i=0;
for(std::map<int, Transform>::iterator iter=poses.begin(); iter!=poses.end(); ++iter, ++i)
{
if(groundTruth.find(iter->first) == groundTruth.end())
{
groundTruth.insert(std::make_pair(iter->first, Transform()));
validIndices[i] = 0;
}
}
path = dir+UDirectory::separator()+dbName+"_gt.txt";
if(!graph::exportPoses(path, outputKittiError?2:0, groundTruth))
{
printf("Could not export the ground truth to \"%s\"!?!\n", path.c_str());
}
else
{
// save valid indices
path = dir+UDirectory::separator()+dbName+"_indices.txt";
FILE * file = 0;
#ifdef _MSC_VER
fopen_s(&file, path.c_str(), "w");
#else
file = fopen(path.c_str(), "w");
#endif
if(file)
{
// VERTEX3 id x y z phi theta psi
for(unsigned int k=0; k<validIndices.size(); ++k)
{
fprintf(file, "%d\n", validIndices[k]);
}
fclose(file);
}
}
}
}
}
}
printf(" %s (%d, s=%.3f):\terror lin=%.3fm (max=%.3fm) ang=%.1fdeg%s, slam: avg=%dms (max=%dms) loops=%d, odom: avg=%dms (max=%dms), camera: avg=%dms, %smap=%dMB\n",
fileName.c_str(),
(int)ids.size(),