2012-06-24 17:19:34 +00:00
|
|
|
/*
|
|
|
|
|
* DBReader.cpp
|
|
|
|
|
*
|
|
|
|
|
* Created on: 2012-06-13
|
|
|
|
|
* Author: mathieu
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
#include "rtabmap/core/DBReader.h"
|
|
|
|
|
#include "rtabmap/core/DBDriver.h"
|
2012-12-11 18:05:05 +00:00
|
|
|
#include "DBDriverSqlite3.h"
|
2012-06-24 17:19:34 +00:00
|
|
|
|
2013-04-30 20:16:01 +00:00
|
|
|
#include <rtabmap/utilite/ULogger.h>
|
|
|
|
|
#include <rtabmap/utilite/UFile.h>
|
2012-06-24 17:19:34 +00:00
|
|
|
|
2013-02-04 16:38:00 +00:00
|
|
|
#include "rtabmap/core/CameraEvent.h"
|
2013-12-11 00:12:44 +00:00
|
|
|
#include "rtabmap/core/OdometryEvent.h"
|
|
|
|
|
#include "rtabmap/core/util3d.h"
|
2012-12-11 18:05:05 +00:00
|
|
|
|
2012-06-24 17:19:34 +00:00
|
|
|
namespace rtabmap {
|
|
|
|
|
|
|
|
|
|
DBReader::DBReader(const std::string & databasePath,
|
2013-12-11 00:12:44 +00:00
|
|
|
float frameRate,
|
2014-02-28 22:11:36 +00:00
|
|
|
bool odometryIgnored,
|
|
|
|
|
float delayToStartSec) :
|
2012-06-24 17:19:34 +00:00
|
|
|
_path(databasePath),
|
|
|
|
|
_frameRate(frameRate),
|
2013-12-11 00:12:44 +00:00
|
|
|
_odometryIgnored(odometryIgnored),
|
2014-02-28 22:11:36 +00:00
|
|
|
_delayToStartSec(delayToStartSec),
|
2012-06-24 17:19:34 +00:00
|
|
|
_dbDriver(0),
|
|
|
|
|
_currentId(_ids.end())
|
|
|
|
|
{
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
DBReader::~DBReader()
|
|
|
|
|
{
|
|
|
|
|
if(_dbDriver)
|
|
|
|
|
{
|
|
|
|
|
_dbDriver->closeConnection();
|
|
|
|
|
delete _dbDriver;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2012-12-11 18:05:05 +00:00
|
|
|
bool DBReader::init(int startIndex)
|
2012-06-24 17:19:34 +00:00
|
|
|
{
|
|
|
|
|
if(_dbDriver)
|
|
|
|
|
{
|
|
|
|
|
_dbDriver->closeConnection();
|
|
|
|
|
delete _dbDriver;
|
|
|
|
|
_dbDriver = 0;
|
|
|
|
|
}
|
|
|
|
|
_ids.clear();
|
|
|
|
|
_currentId=_ids.end();
|
|
|
|
|
|
|
|
|
|
if(!UFile::exists(_path))
|
|
|
|
|
{
|
|
|
|
|
UERROR("Database path does not exist (%s)", _path.c_str());
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
rtabmap::ParametersMap parameters;
|
|
|
|
|
parameters.insert(rtabmap::ParametersPair(rtabmap::Parameters::kDbSqlite3InMemory(), "false"));
|
2012-12-11 18:05:05 +00:00
|
|
|
_dbDriver = new DBDriverSqlite3(parameters);
|
2012-06-24 17:19:34 +00:00
|
|
|
if(!_dbDriver)
|
|
|
|
|
{
|
|
|
|
|
UERROR("Driver doesn't exist.");
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
if(!_dbDriver->openConnection(_path))
|
|
|
|
|
{
|
|
|
|
|
UERROR("Can't open database %s", _path.c_str());
|
|
|
|
|
delete _dbDriver;
|
|
|
|
|
_dbDriver = 0;
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
_dbDriver->getAllNodeIds(_ids);
|
|
|
|
|
_currentId = _ids.begin();
|
2012-12-11 18:05:05 +00:00
|
|
|
if(startIndex>0 && _ids.size())
|
|
|
|
|
{
|
|
|
|
|
std::set<int>::iterator iter = _ids.lower_bound(startIndex);
|
|
|
|
|
if(iter == _ids.end())
|
|
|
|
|
{
|
|
|
|
|
UWARN("Start index is too high (%d), the last in database is %d. Starting from beginning...", startIndex, *_ids.rbegin());
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
_currentId = iter;
|
|
|
|
|
}
|
|
|
|
|
}
|
2012-06-24 17:19:34 +00:00
|
|
|
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void DBReader::setFrameRate(float frameRate)
|
|
|
|
|
{
|
|
|
|
|
if(frameRate >= 0.0f)
|
|
|
|
|
{
|
|
|
|
|
_frameRate = frameRate;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void DBReader::mainLoopBegin()
|
|
|
|
|
{
|
2014-02-28 22:11:36 +00:00
|
|
|
if(_delayToStartSec > 0.0f)
|
|
|
|
|
{
|
|
|
|
|
uSleep(_delayToStartSec*1000.0f);
|
|
|
|
|
}
|
2012-06-24 17:19:34 +00:00
|
|
|
_timer.start();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void DBReader::mainLoop()
|
|
|
|
|
{
|
2013-12-11 00:12:44 +00:00
|
|
|
cv::Mat image, depth, depth2d;
|
2014-07-26 04:36:00 +00:00
|
|
|
float fx,fy,cx,cy;
|
2013-12-11 00:12:44 +00:00
|
|
|
Transform localTransform, pose;
|
2014-07-26 04:36:00 +00:00
|
|
|
this->getNextImage(image, depth, depth2d, fx, fy, cx, cy, localTransform, pose);
|
2012-12-11 18:05:05 +00:00
|
|
|
if(!image.empty())
|
2012-06-24 17:19:34 +00:00
|
|
|
{
|
2013-12-11 00:12:44 +00:00
|
|
|
if(depth.empty())
|
|
|
|
|
{
|
|
|
|
|
this->post(new CameraEvent(image));
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
if(!_odometryIgnored)
|
|
|
|
|
{
|
2014-07-26 04:36:00 +00:00
|
|
|
Image data(image, depth, depth2d, fx, fy, cx, cy, pose, localTransform);
|
2013-12-11 00:12:44 +00:00
|
|
|
this->post(new OdometryEvent(data));
|
2014-06-23 00:26:14 +00:00
|
|
|
if(pose.isNull())
|
|
|
|
|
{
|
|
|
|
|
UWARN("Reading the database: odometry is null! "
|
|
|
|
|
"Please set \"Ignore odometry = true\" if there is "
|
|
|
|
|
"no odometry in the database.");
|
|
|
|
|
}
|
2013-12-11 00:12:44 +00:00
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
// without odometry
|
2014-07-26 04:36:00 +00:00
|
|
|
this->post(new CameraEvent(image, depth, depth2d, fx, fy, cx, cy, localTransform));
|
2013-12-11 00:12:44 +00:00
|
|
|
}
|
|
|
|
|
}
|
2012-06-24 17:19:34 +00:00
|
|
|
}
|
|
|
|
|
else if(!this->isKilled())
|
|
|
|
|
{
|
2013-12-11 00:12:44 +00:00
|
|
|
UINFO("no more images...");
|
2012-06-24 17:19:34 +00:00
|
|
|
this->kill();
|
2013-12-11 00:12:44 +00:00
|
|
|
this->post(new CameraEvent());
|
2012-06-24 17:19:34 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
2013-12-11 00:12:44 +00:00
|
|
|
void DBReader::getNextImage(
|
|
|
|
|
cv::Mat & image,
|
|
|
|
|
cv::Mat & depth,
|
|
|
|
|
cv::Mat & depth2d,
|
2014-07-26 04:36:00 +00:00
|
|
|
float & fx,
|
|
|
|
|
float & fy,
|
|
|
|
|
float & cx,
|
|
|
|
|
float & cy,
|
2013-12-11 00:12:44 +00:00
|
|
|
Transform & localTransform,
|
|
|
|
|
Transform & pose)
|
2012-06-24 17:19:34 +00:00
|
|
|
{
|
|
|
|
|
if(_dbDriver)
|
|
|
|
|
{
|
|
|
|
|
float frameRate = _frameRate;
|
|
|
|
|
if(frameRate>0.0f)
|
|
|
|
|
{
|
|
|
|
|
int sleepTime = (1000.0f/frameRate - 1000.0f*_timer.getElapsedTime());
|
|
|
|
|
if(sleepTime > 2)
|
|
|
|
|
{
|
|
|
|
|
uSleep(sleepTime-2);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Add precision at the cost of a small overhead
|
|
|
|
|
while(_timer.getElapsedTime() < 1.0/double(frameRate)-0.000001)
|
|
|
|
|
{
|
|
|
|
|
//
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
double slept = _timer.getElapsedTime();
|
|
|
|
|
_timer.start();
|
|
|
|
|
UDEBUG("slept=%fs vs target=%fs", slept, 1.0/double(frameRate));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if(!this->isKilled() && _currentId != _ids.end())
|
|
|
|
|
{
|
2013-12-11 00:12:44 +00:00
|
|
|
std::vector<unsigned char> imageBytes;
|
|
|
|
|
std::vector<unsigned char> depthBytes;
|
|
|
|
|
std::vector<unsigned char> depth2dBytes;
|
|
|
|
|
int mapId;
|
2014-07-26 04:36:00 +00:00
|
|
|
_dbDriver->getNodeData(*_currentId, imageBytes, depthBytes, depth2dBytes, fx, fy, cx, cy, localTransform);
|
2013-12-11 00:12:44 +00:00
|
|
|
_dbDriver->getPose(*_currentId, pose, mapId);
|
2012-06-24 17:19:34 +00:00
|
|
|
++_currentId;
|
2013-12-11 00:12:44 +00:00
|
|
|
if(imageBytes.empty())
|
2012-06-24 17:19:34 +00:00
|
|
|
{
|
2013-12-11 00:12:44 +00:00
|
|
|
UWARN("No image loaded from the database for id=%d!", *_currentId);
|
2012-06-24 17:19:34 +00:00
|
|
|
}
|
2013-12-11 00:12:44 +00:00
|
|
|
|
|
|
|
|
util3d::CompressionThread ctImage(imageBytes, true);
|
|
|
|
|
util3d::CompressionThread ctDepth(depthBytes, true);
|
|
|
|
|
util3d::CompressionThread ctDepth2D(depth2dBytes, false);
|
|
|
|
|
ctImage.start();
|
|
|
|
|
ctDepth.start();
|
|
|
|
|
ctDepth2D.start();
|
|
|
|
|
ctImage.join();
|
|
|
|
|
ctDepth.join();
|
|
|
|
|
ctDepth2D.join();
|
|
|
|
|
image = ctImage.getUncompressedData();
|
|
|
|
|
depth = ctDepth.getUncompressedData();
|
|
|
|
|
depth2d = ctDepth2D.getUncompressedData();
|
2012-06-24 17:19:34 +00:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
UERROR("Not initialized...");
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
} /* namespace rtabmap */
|