rtabmap: removed all UtiLite include references for main RTAB-Map classes (to avoid linking to UtiLite when using RTAB-Map as c++ library)

git-svn-id: http://rtabmap.googlecode.com/svn/trunk/rtabmap@811 f169173b-cf89-36c8-b27e-44dbe73f0c83
This commit is contained in:
matlabbe
2013-02-04 16:38:00 +00:00
parent e8e75a9d40
commit 00ac36747e
14 changed files with 462 additions and 294 deletions

View File

@@ -23,75 +23,29 @@
#include <opencv2/highgui/highgui.hpp>
#include <opencv2/features2d/features2d.hpp>
#include <utilite/UThreadNode.h>
#include <utilite/UEventsHandler.h>
#include <utilite/UEvent.h>
#include <utilite/UDirectory.h>
#include <utilite/UTimer.h>
#include "rtabmap/core/Parameters.h"
#include "rtabmap/core/Features2d.h"
#include "rtabmap/core/Image.h"
#include "rtabmap/core/Features2d.h"
#include <set>
#include <stack>
#include <list>
#include <vector>
class UDirectory;
class UTimer;
namespace rtabmap
{
class CameraEvent :
public UEvent
{
public:
enum Code {
kCodeFeatures,
kCodeImage,
kCodeNoMoreImages
};
public:
CameraEvent(const cv::Mat & image, int cameraId = 0) :
UEvent(kCodeImage),
_cameraId(cameraId),
_image(image)
{
}
CameraEvent(const cv::Mat & descriptors, const std::vector<cv::KeyPoint> & keypoints, const cv::Mat & image = cv::Mat(), int cameraId = 0) :
UEvent(kCodeFeatures),
_cameraId(cameraId),
_image(image, 0, descriptors, keypoints)
{
}
CameraEvent(int cameraId = 0) :
UEvent(kCodeNoMoreImages),
_cameraId(cameraId)
{
}
int cameraId() const {return _cameraId;}
// Image or descriptors
const Image & image() const {return _image;}
virtual ~CameraEvent() {}
virtual std::string getClassName() const {return std::string("CameraEvent");}
private:
int _cameraId;
Image _image;
};
class KeypointDetector;
class KeypointDescriptor;
/**
* Class Camera
*
*/
class RTABMAP_EXP Camera :
public UThreadNode,
public UEventsHandler
class RTABMAP_EXP Camera
{
public:
enum State {kStateCapturing, kStateChangingParameters};
public:
virtual ~Camera();
cv::Mat takeImage();
@@ -99,8 +53,6 @@ public:
virtual bool init() = 0;
//getters
bool isPaused() const {return !this->isRunning();}
bool isCapturing() const {return this->isRunning();}
void getImageSize(unsigned int & width, unsigned int & height);
float getImageRate() const {return _imageRate;}
bool isFeaturesExtracted() const {return _featuresExtracted;}
@@ -110,7 +62,6 @@ public:
KeypointDetector::DetectorType detector = KeypointDetector::kDetectorUndef,
KeypointDescriptor::DescriptorType descriptor = KeypointDescriptor::kDescriptorUndef);
void setImageRate(float imageRate) {_imageRate = imageRate;}
void setAutoRestart(bool autoRestart) {_autoRestart = autoRestart;}
void setImageSize(unsigned int width, unsigned int height);
@@ -123,30 +74,17 @@ protected:
*
* @param imageRate : image/second , 0 for fast as the camera can
*/
Camera(float imageRate = 0, bool autoRestart = false, unsigned int imageWidth = 0, unsigned int imageHeight = 0, unsigned int framesDropped = 0, int id = 0);
Camera(float imageRate = 0, unsigned int imageWidth = 0, unsigned int imageHeight = 0, unsigned int framesDropped = 0, int id = 0);
virtual void handleEvent(UEvent* anEvent);
virtual cv::Mat captureImage() = 0;
private:
virtual void mainLoopBegin();
virtual void mainLoop();
void process();
void pushNewState(State newState, const ParametersMap & parameters = ParametersMap());
private:
float _imageRate;
int _id;
bool _autoRestart;
unsigned int _imageWidth;
unsigned int _imageHeight;
unsigned int _framesDropped;
UTimer _frameRateTimer;
UMutex _imageSizeMutex;
UMutex _stateMutex;
std::stack<State> _state;
std::stack<ParametersMap> _stateParam;
UTimer * _frameRateTimer;
bool _featuresExtracted;
KeypointDetector * _keypointDetector;
@@ -154,7 +92,6 @@ private:
};
/////////////////////////
// CameraImages
/////////////////////////
@@ -166,7 +103,6 @@ public:
int startAt = 1,
bool refreshDir = false,
float imageRate = 0,
bool autoRestart = false,
unsigned int imageWidth = 0,
unsigned int imageHeight = 0,
unsigned int framesDropped = 0,
@@ -185,12 +121,9 @@ private:
// If the list of files in the directory is refreshed
// on each call of takeImage()
bool _refreshDir;
UDirectory _dir;
int _count;
UDirectory * _dir;
std::string _lastFileName;
};
@@ -208,14 +141,12 @@ public:
public:
CameraVideo(int usbDevice = 0,
float imageRate = 0,
bool autoRestart = false,
unsigned int imageWidth = 0,
unsigned int imageHeight = 0,
unsigned int framesDropped = 0,
int id = 0);
CameraVideo(const std::string & filePath,
float imageRate = 0,
bool autoRestart = false,
unsigned int imageWidth = 0,
unsigned int imageHeight = 0,
unsigned int framesDropped = 0,

View File

@@ -0,0 +1,72 @@
/*
* Copyright (C) 2010-2011, Mathieu Labbe and IntRoLab - Universite de Sherbrooke
*
* This file is part of RTAB-Map.
*
* RTAB-Map is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* RTAB-Map is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with RTAB-Map. If not, see <http://www.gnu.org/licenses/>.
*/
#pragma once
#include <opencv2/highgui/highgui.hpp>
#include <opencv2/features2d/features2d.hpp>
#include <utilite/UEvent.h>
#include "rtabmap/core/Image.h"
namespace rtabmap
{
class CameraEvent :
public UEvent
{
public:
enum Code {
kCodeFeatures,
kCodeImage,
kCodeNoMoreImages
};
public:
CameraEvent(const cv::Mat & image, int cameraId = 0) :
UEvent(kCodeImage),
_cameraId(cameraId),
_image(image)
{
}
CameraEvent(const cv::Mat & descriptors, const std::vector<cv::KeyPoint> & keypoints, const cv::Mat & image = cv::Mat(), int cameraId = 0) :
UEvent(kCodeFeatures),
_cameraId(cameraId),
_image(image, 0, descriptors, keypoints)
{
}
CameraEvent(int cameraId = 0) :
UEvent(kCodeNoMoreImages),
_cameraId(cameraId)
{
}
int cameraId() const {return _cameraId;}
// Image or descriptors
const Image & image() const {return _image;}
virtual ~CameraEvent() {}
virtual std::string getClassName() const {return std::string("CameraEvent");}
private:
int _cameraId;
Image _image;
};
} // namespace rtabmap

View File

@@ -0,0 +1,74 @@
/*
* Copyright (C) 2010-2011, Mathieu Labbe and IntRoLab - Universite de Sherbrooke
*
* This file is part of RTAB-Map.
*
* RTAB-Map is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* RTAB-Map is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with RTAB-Map. If not, see <http://www.gnu.org/licenses/>.
*/
#pragma once
#include "rtabmap/core/RtabmapExp.h" // DLL export/import defines
#include <utilite/UThreadNode.h>
#include <utilite/UEventsHandler.h>
#include "rtabmap/core/Parameters.h"
#include <stack>
namespace rtabmap
{
class Camera;
/**
* Class CameraThread
*
*/
class RTABMAP_EXP CameraThread :
public UThreadNode,
public UEventsHandler
{
public:
enum State {kStateCapturing, kStateChangingParameters};
public:
// ownership transferred
CameraThread(Camera * camera, bool autoRestart = false);
virtual ~CameraThread();
//getters
bool isPaused() const {return !this->isRunning();}
bool isCapturing() const {return this->isRunning();}
void setAutoRestart(bool autoRestart) {_autoRestart = autoRestart;}
void setImageRate(float imageRate);
protected:
virtual void handleEvent(UEvent* anEvent);
private:
virtual void mainLoop();
void process();
void pushNewState(State newState, const ParametersMap & parameters = ParametersMap());
private:
Camera * _camera;
UMutex _stateMutex;
std::stack<State> _state;
std::stack<ParametersMap> _stateParam;
bool _autoRestart;
};
} // namespace rtabmap

View File

@@ -0,0 +1,53 @@
/*
* Copyright (C) 2010-2011, Mathieu Labbe and IntRoLab - Universite de Sherbrooke
*
* This file is part of RTAB-Map.
*
* RTAB-Map is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* RTAB-Map is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with RTAB-Map. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef PARAMEVENT_H_
#define PARAMEVENT_H_
#include "rtabmap/core/Parameters.h"
#include <utilite/UEvent.h>
namespace rtabmap
{
/**
* The parameters event. This event is used to send
* parameters across the threads.
*/
class ParamEvent : public UEvent
{
public:
ParamEvent(const ParametersMap & parameters) : UEvent(0), parameters_(parameters) {}
ParamEvent(const std::string & parameterKey, const std::string & parameterValue) : UEvent(0)
{
parameters_.insert(std::pair<std::string, std::string>(parameterKey, parameterValue));
}
~ParamEvent() {}
virtual std::string getClassName() const {return "ParamEvent";}
const ParametersMap & getParameters() const {return parameters_;}
private:
ParametersMap parameters_; /**< The parameters map (key,value). */
};
}
#endif /* PARAMEVENT_H_ */

View File

@@ -22,7 +22,6 @@
// default parameters
#include "rtabmap/core/RtabmapExp.h" // DLL export/import defines
#include "utilite/UEvent.h"
#include <string>
#include <map>
@@ -219,27 +218,6 @@ private:
static Parameters instance_;
};
/**
* The parameters event. This event is used to send
* parameters across the threads.
*/
class ParamEvent : public UEvent
{
public:
ParamEvent(const ParametersMap & parameters) : UEvent(0), parameters_(parameters) {}
ParamEvent(const std::string & parameterKey, const std::string & parameterValue) : UEvent(0)
{
parameters_.insert(std::pair<std::string, std::string>(parameterKey, parameterValue));
}
~ParamEvent() {}
virtual std::string getClassName() const {return "ParamEvent";}
const ParametersMap & getParameters() const {return parameters_;}
private:
ParametersMap parameters_; /**< The parameters map (key,value). */
};
}
#endif /* PARAMETERS_H_ */

View File

@@ -22,10 +22,6 @@
#include "rtabmap/core/RtabmapExp.h" // DLL export/import defines
#include <utilite/USemaphore.h>
#include <utilite/UMutex.h>
#include <utilite/UVariant.h>
#include "rtabmap/core/Parameters.h"
#include "rtabmap/core/Image.h"
#include "rtabmap/core/Statistics.h"

View File

@@ -24,6 +24,8 @@
#include <utilite/UThreadNode.h>
#include <utilite/UEventsHandler.h>
#include <utilite/USemaphore.h>
#include <utilite/UMutex.h>
#include "rtabmap/core/RtabmapEvent.h"
#include "rtabmap/core/Image.h"

View File

@@ -12,6 +12,8 @@ SET(SRC_FILES
DBReader.cpp
Camera.cpp
CameraThread.cpp
EpipolarGeometry.cpp
VisualWord.cpp
VWDictionary.cpp

View File

@@ -18,32 +18,33 @@
*/
#include "rtabmap/core/Camera.h"
#include "utilite/UEventsManager.h"
#include "utilite/UConversion.h"
#include "rtabmap/core/DBDriver.h"
#include "rtabmap/core/Features2d.h"
#include "utilite/UStl.h"
#include "utilite/UConversion.h"
#include "utilite/UFile.h"
#include "utilite/UDirectory.h"
#include "utilite/UTimer.h"
#include <utilite/UEventsManager.h>
#include <utilite/UConversion.h>
#include <utilite/UStl.h>
#include <utilite/UConversion.h>
#include <utilite/UFile.h>
#include <utilite/UDirectory.h>
#include <utilite/UTimer.h>
#include <opencv2/imgproc/imgproc.hpp>
namespace rtabmap
{
Camera::Camera(float imageRate,
bool autoRestart,
unsigned int imageWidth,
unsigned int imageHeight,
unsigned int framesDropped,
int id) :
_imageRate(imageRate),
_id(id),
_autoRestart(autoRestart),
_imageWidth(imageWidth),
_imageHeight(imageHeight),
_framesDropped(framesDropped),
_frameRateTimer(new UTimer()),
_featuresExtracted(false),
_keypointDetector(0),
_keypointDescriptor(0)
@@ -52,8 +53,6 @@ Camera::Camera(float imageRate,
Camera::~Camera()
{
UEventsManager::removeHandler(this);
join(true);
if(_keypointDetector)
{
delete _keypointDetector;
@@ -62,6 +61,10 @@ Camera::~Camera()
{
delete _keypointDescriptor;
}
if(_frameRateTimer)
{
delete _frameRateTimer;
}
}
void Camera::setFeaturesExtracted(bool featuresExtracted, KeypointDetector::DetectorType detector, KeypointDescriptor::DescriptorType descriptor)
@@ -78,22 +81,14 @@ void Camera::setFeaturesExtracted(bool featuresExtracted, KeypointDetector::Dete
void Camera::setImageSize(unsigned int width, unsigned int height)
{
_imageSizeMutex.lock();
{
_imageWidth = width;
_imageHeight = height;
}
_imageSizeMutex.unlock();
_imageWidth = width;
_imageHeight = height;
}
void Camera::getImageSize(unsigned int & width, unsigned int & height)
{
_imageSizeMutex.lock();
{
width = _imageWidth;
height = _imageHeight;
}
_imageSizeMutex.unlock();
width = _imageWidth;
height = _imageHeight;
}
void Camera::parseParameters(const ParametersMap & parameters)
@@ -162,68 +157,6 @@ void Camera::parseParameters(const ParametersMap & parameters)
}
}
void Camera::mainLoopBegin()
{
_frameRateTimer.start();
}
void Camera::mainLoop()
{
State state = kStateCapturing;
ParametersMap parameters;
_stateMutex.lock();
{
if(!_state.empty() && !_stateParam.empty())
{
state = _state.top();
_state.pop();
parameters = _stateParam.top();
_stateParam.pop();
}
}
_stateMutex.unlock();
if(state == kStateCapturing)
{
process();
}
else if(state == kStateChangingParameters)
{
this->parseParameters(parameters);
}
}
void Camera::pushNewState(State newState, const ParametersMap & parameters)
{
ULOGGER_DEBUG("to %d", newState);
_stateMutex.lock();
{
_state.push(newState);
_stateParam.push(parameters);
}
_stateMutex.unlock();
}
void Camera::handleEvent(UEvent* anEvent)
{
if(anEvent->getClassName().compare("ParamEvent") == 0)
{
if(this->isIdle())
{
_stateMutex.lock();
this->parseParameters(((ParamEvent*)anEvent)->getParameters());
_stateMutex.unlock();
}
else
{
ULOGGER_DEBUG("changing parameters");
pushNewState(kStateChangingParameters, ((ParamEvent*)anEvent)->getParameters());
}
}
}
cv::Mat Camera::takeImage()
{
cv::Mat descriptors;
@@ -242,104 +175,67 @@ cv::Mat Camera::takeImage(cv::Mat & descriptors, std::vector<cv::KeyPoint> & key
float imageRate = _imageRate;
if(imageRate>0)
{
int sleepTime = (1000.0f/imageRate - 1000.0f*_frameRateTimer.getElapsedTime());
int sleepTime = (1000.0f/imageRate - 1000.0f*_frameRateTimer->getElapsedTime());
if(sleepTime > 2)
{
uSleep(sleepTime-2);
}
// Add precision at the cost of a small overhead
while(_frameRateTimer.getElapsedTime() < 1.0/double(imageRate)-0.000001)
while(_frameRateTimer->getElapsedTime() < 1.0/double(imageRate)-0.000001)
{
//
}
double slept = _frameRateTimer.getElapsedTime();
_frameRateTimer.start();
double slept = _frameRateTimer->getElapsedTime();
_frameRateTimer->start();
UDEBUG("slept=%fs vs target=%fs", slept, 1.0/double(imageRate));
}
cv::Mat img;
if(!this->isKilled())
UTimer timer;
img = this->captureImage();
UDEBUG("Time capturing image = %fs", timer.ticks());
if(!img.empty())
{
UTimer timer;
img = this->captureImage();
UDEBUG("Time capturing image = %fs", timer.ticks());
if(!img.empty())
if(img.depth() != CV_8U)
{
if(img.depth() != CV_8U)
{
UWARN("Images should have already 8U depth !?");
cv::Mat tmp = img;
img = cv::Mat();
tmp.convertTo(img, CV_8U);
UDEBUG("Time converting image to 8U = %fs", timer.ticks());
}
UWARN("Images should have already 8U depth !?");
cv::Mat tmp = img;
img = cv::Mat();
tmp.convertTo(img, CV_8U);
UDEBUG("Time converting image to 8U = %fs", timer.ticks());
}
if(_featuresExtracted && _keypointDetector && _keypointDescriptor)
{
keypoints = _keypointDetector->generateKeypoints(img);
descriptors = _keypointDescriptor->generateDescriptors(img, keypoints);
UDEBUG("Post treatment time = %fs", timer.ticks());
}
if(_featuresExtracted && _keypointDetector && _keypointDescriptor)
{
keypoints = _keypointDetector->generateKeypoints(img);
descriptors = _keypointDescriptor->generateDescriptors(img, keypoints);
UDEBUG("Post treatment time = %fs", timer.ticks());
}
if(_framesDropped)
if(_framesDropped)
{
unsigned int count = 0;
while(count++ < _framesDropped)
{
unsigned int count = 0;
while(count++ < _framesDropped)
cv::Mat tmp = this->captureImage();
if(!tmp.empty())
{
cv::Mat tmp = this->captureImage();
if(!tmp.empty())
{
UDEBUG("frame dropped (%d/%d)", (int)count, (int)_framesDropped);
}
else
{
break;
}
UDEBUG("frame dropped (%d/%d)", (int)count, (int)_framesDropped);
}
else
{
break;
}
UDEBUG("Frames dropped time = %fs", timer.ticks());
}
UDEBUG("Frames dropped time = %fs", timer.ticks());
}
}
return img;
}
void Camera::process()
{
UTimer timer;
ULOGGER_DEBUG("Camera::process()");
cv::Mat descriptors;
std::vector<cv::KeyPoint> keypoints;
cv::Mat img = this->takeImage(descriptors, keypoints);
if(!img.empty())
{
if(_featuresExtracted)
{
this->post(new CameraEvent(descriptors, keypoints, img, _id));
}
else
{
this->post(new CameraEvent(img, _id));
}
}
else if(!this->isKilled())
{
if(_autoRestart)
{
this->init();
}
else
{
ULOGGER_DEBUG("Camera::process() : no more images...");
this->kill();
this->post(new CameraEvent(_id));
}
}
}
/////////////////////////
// CameraImages
/////////////////////////
@@ -347,57 +243,68 @@ CameraImages::CameraImages(const std::string & path,
int startAt,
bool refreshDir,
float imageRate,
bool autoRestart,
unsigned int imageWidth,
unsigned int imageHeight,
unsigned int framesDropped,
int id) :
Camera(imageRate, autoRestart, imageWidth, imageHeight, framesDropped, id),
Camera(imageRate, imageWidth, imageHeight, framesDropped, id),
_path(path),
_startAt(startAt),
_refreshDir(refreshDir),
_count(0)
_count(0),
_dir(0)
{
}
CameraImages::~CameraImages(void)
{
join(true);
if(_dir)
{
delete _dir;
}
}
bool CameraImages::init()
{
UDEBUG("");
_dir = UDirectory(_path, "jpg ppm png bmp pnm");
if(_dir)
{
_dir->setPath(_path, "jpg ppm png bmp pnm");
}
else
{
_dir = new UDirectory(_path, "jpg ppm png bmp pnm");
}
_count = 0;
if(_path[_path.size()-1] != '\\' && _path[_path.size()-1] != '/')
{
_path.append("/");
}
if(!_dir.isValid())
if(!_dir->isValid())
{
ULOGGER_ERROR("Directory path is not valid \"%s\"", _path.c_str());
}
else if(_dir.getFileNames().size() == 0)
else if(_dir->getFileNames().size() == 0)
{
UWARN("Directory is empty \"%s\"", _path.c_str());
}
return _dir.isValid();
return _dir->isValid();
}
cv::Mat CameraImages::captureImage()
{
UDEBUG("");
cv::Mat img;
if(_dir.isValid())
if(_dir->isValid())
{
if(_refreshDir)
{
_dir.update();
_dir->update();
}
if(_startAt == 0)
{
const std::list<std::string> & fileNames = _dir.getFileNames();
const std::list<std::string> & fileNames = _dir->getFileNames();
if(fileNames.size())
{
if(_lastFileName.empty() || uStrNumCmp(_lastFileName,*fileNames.rbegin()) < 0)
@@ -412,11 +319,11 @@ cv::Mat CameraImages::captureImage()
{
std::string fileName;
std::string fullPath;
fileName = _dir.getNextFileName();
fileName = _dir->getNextFileName();
if(fileName.size())
{
fullPath = _path + fileName;
while(++_count < _startAt && (fileName = _dir.getNextFileName()).size())
while(++_count < _startAt && (fileName = _dir->getNextFileName()).size())
{
fullPath = _path + fileName;
}
@@ -473,12 +380,11 @@ cv::Mat CameraImages::captureImage()
/////////////////////////
CameraVideo::CameraVideo(int usbDevice,
float imageRate,
bool autoRestart,
unsigned int imageWidth,
unsigned int imageHeight,
unsigned int framesDropped,
int id) :
Camera(imageRate, autoRestart, imageWidth, imageHeight, framesDropped, id),
Camera(imageRate, imageWidth, imageHeight, framesDropped, id),
_src(kUsbDevice),
_usbDevice(usbDevice)
{
@@ -487,12 +393,11 @@ CameraVideo::CameraVideo(int usbDevice,
CameraVideo::CameraVideo(const std::string & filePath,
float imageRate,
bool autoRestart,
unsigned int imageWidth,
unsigned int imageHeight,
unsigned int framesDropped,
int id) :
Camera(imageRate, autoRestart, imageWidth, imageHeight, framesDropped, id),
Camera(imageRate, imageWidth, imageHeight, framesDropped, id),
_filePath(filePath),
_src(kVideoFile),
_usbDevice(0)
@@ -501,7 +406,6 @@ CameraVideo::CameraVideo(const std::string & filePath,
CameraVideo::~CameraVideo()
{
join(true);
_capture.release();
}

View File

@@ -0,0 +1,141 @@
/*
* Copyright (C) 2010-2011, Mathieu Labbe and IntRoLab - Universite de Sherbrooke
*
* This file is part of RTAB-Map.
*
* RTAB-Map is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* RTAB-Map is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with RTAB-Map. If not, see <http://www.gnu.org/licenses/>.
*/
#include "rtabmap/core/CameraThread.h"
#include "rtabmap/core/Camera.h"
#include "rtabmap/core/CameraEvent.h"
#include "rtabmap/core/ParamEvent.h"
#include <utilite/UEventsManager.h>
#include <utilite/UTimer.h>
namespace rtabmap
{
// ownership transferred
CameraThread::CameraThread(Camera * camera, bool autoRestart) :
_camera(camera),
_autoRestart(autoRestart)
{
UASSERT(_camera != 0);
}
CameraThread::~CameraThread()
{
UEventsManager::removeHandler(this);
join(true);
delete _camera;
}
void CameraThread::mainLoop()
{
State state = kStateCapturing;
ParametersMap parameters;
_stateMutex.lock();
{
if(!_state.empty() && !_stateParam.empty())
{
state = _state.top();
_state.pop();
parameters = _stateParam.top();
_stateParam.pop();
}
}
_stateMutex.unlock();
if(state == kStateCapturing)
{
process();
}
else if(state == kStateChangingParameters)
{
_camera->parseParameters(parameters);
}
}
void CameraThread::pushNewState(State newState, const ParametersMap & parameters)
{
ULOGGER_DEBUG("to %d", newState);
_stateMutex.lock();
{
_state.push(newState);
_stateParam.push(parameters);
}
_stateMutex.unlock();
}
void CameraThread::setImageRate(float imageRate)
{
_camera->setImageRate(imageRate);
}
void CameraThread::handleEvent(UEvent* anEvent)
{
if(anEvent->getClassName().compare("ParamEvent") == 0)
{
if(this->isIdle())
{
_stateMutex.lock();
_camera->parseParameters(((ParamEvent*)anEvent)->getParameters());
_stateMutex.unlock();
}
else
{
ULOGGER_DEBUG("changing parameters");
pushNewState(kStateChangingParameters, ((ParamEvent*)anEvent)->getParameters());
}
}
}
void CameraThread::process()
{
UTimer timer;
ULOGGER_DEBUG("Camera::process()");
cv::Mat descriptors;
std::vector<cv::KeyPoint> keypoints;
cv::Mat img = _camera->takeImage(descriptors, keypoints);
if(!img.empty() && !this->isKilled())
{
if(_camera->isFeaturesExtracted())
{
this->post(new CameraEvent(descriptors, keypoints, img, _camera->id()));
}
else
{
this->post(new CameraEvent(img, _camera->id()));
}
}
else if(!this->isKilled())
{
if(_autoRestart)
{
_camera->init();
}
else
{
ULOGGER_DEBUG("Camera::process() : no more images...");
this->kill();
this->post(new CameraEvent(_camera->id()));
}
}
}
} // namespace rtabmap

View File

@@ -13,7 +13,7 @@
#include <utilite/UEventsManager.h>
#include <utilite/UFile.h>
#include "rtabmap/core/Camera.h"
#include "rtabmap/core/CameraEvent.h"
namespace rtabmap {

View File

@@ -21,6 +21,8 @@
#include "rtabmap/core/RtabmapThread.h"
#include "rtabmap/core/RtabmapEvent.h"
#include "rtabmap/core/Camera.h"
#include "rtabmap/core/CameraEvent.h"
#include "rtabmap/core/ParamEvent.h"
#include <utilite/ULogger.h>
#include <utilite/UEventsManager.h>