DataRecorder.cpp
Go to the documentation of this file.
00001 /*
00002 Copyright (c) 2010-2014, Mathieu Labbe - IntRoLab - Universite de Sherbrooke
00003 All rights reserved.
00004 
00005 Redistribution and use in source and binary forms, with or without
00006 modification, are permitted provided that the following conditions are met:
00007     * Redistributions of source code must retain the above copyright
00008       notice, this list of conditions and the following disclaimer.
00009     * Redistributions in binary form must reproduce the above copyright
00010       notice, this list of conditions and the following disclaimer in the
00011       documentation and/or other materials provided with the distribution.
00012     * Neither the name of the Universite de Sherbrooke nor the
00013       names of its contributors may be used to endorse or promote products
00014       derived from this software without specific prior written permission.
00015 
00016 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
00017 ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
00018 WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
00019 DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY
00020 DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
00021 (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
00022 LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
00023 ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
00024 (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
00025 SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
00026 */
00027 
00028 #include "rtabmap/gui/DataRecorder.h"
00029 
00030 #include <rtabmap/utilite/ULogger.h>
00031 #include <rtabmap/utilite/UTimer.h>
00032 #include <rtabmap/core/Memory.h>
00033 #include <rtabmap/core/Signature.h>
00034 #include <rtabmap/core/CameraEvent.h>
00035 #include <rtabmap/core/util3d.h>
00036 #include <rtabmap/gui/ImageView.h>
00037 #include <rtabmap/gui/UCv2Qt.h>
00038 #include <QtCore/QMetaType>
00039 #include <QMessageBox>
00040 #include <QtGui/QCloseEvent>
00041 #include <QLabel>
00042 #include <QVBoxLayout>
00043 
00044 namespace rtabmap {
00045 
00046 
00047 DataRecorder::DataRecorder(QWidget * parent) :
00048                 QWidget(parent),
00049         memory_(0),
00050         imageView_(new ImageView(this)),
00051         label_(new QLabel(this)),
00052         processingImages_(false),
00053         count_(0),
00054         totalSizeKB_(0)
00055 {
00056         qRegisterMetaType<cv::Mat>("cv::Mat");
00057 
00058         imageView_->setImageDepthShown(true);
00059         imageView_->setMinimumSize(320, 240);
00060         QVBoxLayout * layout = new QVBoxLayout(this);
00061         layout->setMargin(0);
00062         layout->addWidget(imageView_);
00063         layout->addWidget(label_);
00064         layout->setStretch(0,1);
00065         this->setLayout(layout);
00066 }
00067 bool DataRecorder::init(const QString & path, bool recordInRAM)
00068 {
00069         UScopeMutex scope(memoryMutex_);
00070         if(!memory_)
00071         {
00072                 ParametersMap customParameters;
00073                 customParameters.insert(ParametersPair(Parameters::kMemRehearsalSimilarity(), "1.0")); // desactivate rehearsal
00074                 customParameters.insert(ParametersPair(Parameters::kKpWordsPerImage(), "-1")); // desactivate keypoints extraction
00075                 customParameters.insert(ParametersPair(Parameters::kMemBinDataKept(), "true")); // to keep images
00076                 if(!recordInRAM)
00077                 {
00078                         customParameters.insert(ParametersPair(Parameters::kDbSqlite3InMemory(), "false"));
00079                 }
00080                 memory_ = new Memory();
00081                 if(!memory_->init(path.toStdString(), true, customParameters))
00082                 {
00083                         delete memory_;
00084                         memory_ = 0;
00085                         UERROR("Error initializing the memory.");
00086                         return false;
00087                 }
00088                 path_ = path;
00089                 return true;
00090         }
00091         else
00092         {
00093                 UERROR("Already initialized, close it first.");
00094                 return false;
00095         }
00096 }
00097 
00098 void DataRecorder::closeRecorder()
00099 {
00100         memoryMutex_.lock();
00101         if(memory_)
00102         {
00103                 delete memory_;
00104                 memory_ = 0;
00105                 UINFO("Data recorded to \"%s\".", this->path().toStdString().c_str());
00106         }
00107         memoryMutex_.unlock();
00108         processingImages_ = false;
00109         count_ = 0;
00110         totalSizeKB_ = 0;
00111         if(this->isVisible())
00112         {
00113                 QMessageBox::information(this, tr("Data recorder"), tr("Data recorded to \"%1\".").arg(this->path()));
00114         }
00115 }
00116 
00117 DataRecorder::~DataRecorder()
00118 {
00119         this->unregisterFromEventsManager();
00120         this->closeRecorder();
00121 }
00122 
00123 void DataRecorder::addData(const rtabmap::SensorData & data)
00124 {
00125         memoryMutex_.lock();
00126         if(memory_)
00127         {
00128                 if(memory_->getStMem().size() == 0 && data.id() > 0)
00129                 {
00130                         ParametersMap customParameters;
00131                         customParameters.insert(ParametersPair(Parameters::kMemGenerateIds(), "false")); // use id from data
00132                         memory_->parseParameters(customParameters);
00133                 }
00134 
00135                 //save to database
00136                 UTimer time;
00137                 memory_->update(data);
00138                 const Signature * s = memory_->getLastWorkingSignature();
00139                 totalSizeKB_ += (int)s->getImageCompressed().total()/1000;
00140                 totalSizeKB_ += (int)s->getDepthCompressed().total()/1000;
00141                 memory_->cleanup();
00142 
00143                 if(++count_ % 30)
00144                 {
00145                         memory_->emptyTrash();
00146                 }
00147                 UDEBUG("Time to process a message = %f s", time.ticks());
00148         }
00149         memoryMutex_.unlock();
00150 }
00151 
00152 void DataRecorder::showImage(const cv::Mat & image, const cv::Mat & depth)
00153 {
00154         processingImages_ = true;
00155         imageView_->setImage(uCvMat2QImage(image));
00156         imageView_->setImageDepth(uCvMat2QImage(depth));
00157         label_->setText(tr("Images=%1 (~%2 MB)").arg(count_).arg(totalSizeKB_/1000));
00158         processingImages_ = false;
00159 }
00160 
00161 void DataRecorder::closeEvent(QCloseEvent* event)
00162 {
00163         this->closeRecorder();
00164         event->accept();
00165 }
00166 
00167 void DataRecorder::handleEvent(UEvent * event)
00168 {
00169         if(memory_)
00170         {
00171                 if(event->getClassName().compare("CameraEvent") == 0)
00172                 {
00173                         CameraEvent * camEvent = (CameraEvent*)event;
00174                         if(camEvent->getCode() == CameraEvent::kCodeImageDepth ||
00175                            camEvent->getCode() == CameraEvent::kCodeImage)
00176                         {
00177                                 if(camEvent->data().isValid())
00178                                 {
00179                                         UINFO("Receiving rate = %f Hz", 1.0f/timer_.ticks());
00180                                         this->addData(camEvent->data());
00181 
00182                                         if(!processingImages_ && this->isVisible() && camEvent->data().isValid())
00183                                         {
00184                                                 processingImages_ = true;
00185                                                 QMetaObject::invokeMethod(this, "showImage",
00186                                                                 Q_ARG(cv::Mat, camEvent->data().image()),
00187                                                                 Q_ARG(cv::Mat, camEvent->data().depthOrRightImage()));
00188                                         }
00189                                 }
00190                         }
00191                 }
00192         }
00193 }
00194 
00195 } /* namespace rtabmap */


rtabmap
Author(s): Mathieu Labbe
autogenerated on Fri Aug 28 2015 12:51:31