DataRecorder.cpp
Go to the documentation of this file.
1 /*
2 Copyright (c) 2010-2016, Mathieu Labbe - IntRoLab - Universite de Sherbrooke
3 All rights reserved.
4 
5 Redistribution and use in source and binary forms, with or without
6 modification, are permitted provided that the following conditions are met:
7  * Redistributions of source code must retain the above copyright
8  notice, this list of conditions and the following disclaimer.
9  * Redistributions in binary form must reproduce the above copyright
10  notice, this list of conditions and the following disclaimer in the
11  documentation and/or other materials provided with the distribution.
12  * Neither the name of the Universite de Sherbrooke nor the
13  names of its contributors may be used to endorse or promote products
14  derived from this software without specific prior written permission.
15 
16 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
17 ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19 DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY
20 DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21 (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22 LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
23 ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25 SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */
27 
29 
31 #include <rtabmap/utilite/UTimer.h>
32 #include <rtabmap/core/Memory.h>
33 #include <rtabmap/core/Signature.h>
35 #include <rtabmap/core/util3d.h>
36 #include <rtabmap/gui/ImageView.h>
37 #include <rtabmap/utilite/UCv2Qt.h>
38 #include <QtCore/QMetaType>
39 #include <QMessageBox>
40 #include <QtGui/QCloseEvent>
41 #include <QLabel>
42 #include <QVBoxLayout>
43 
44 namespace rtabmap {
45 
46 
47 DataRecorder::DataRecorder(QWidget * parent) :
48  QWidget(parent),
49  memory_(0),
50  imageView_(new ImageView(this)),
51  label_(new QLabel(this)),
52  processingImages_(false),
53  count_(0),
54  totalSizeKB_(0)
55 {
56  qRegisterMetaType<cv::Mat>("cv::Mat");
57 
59  imageView_->setMinimumSize(320, 240);
60  QVBoxLayout * layout = new QVBoxLayout(this);
61  layout->setMargin(0);
62  layout->addWidget(imageView_);
63  layout->addWidget(label_);
64  layout->setStretch(0,1);
65  this->setLayout(layout);
66 }
67 bool DataRecorder::init(const QString & path, bool recordInRAM)
68 {
70  if(!memory_)
71  {
72  ParametersMap customParameters;
73  customParameters.insert(ParametersPair(Parameters::kMemRehearsalSimilarity(), "1.0")); // deactivate rehearsal
74  customParameters.insert(ParametersPair(Parameters::kKpMaxFeatures(), "-1")); // deactivate keypoints extraction
75  customParameters.insert(ParametersPair(Parameters::kMemBinDataKept(), "true")); // to keep images
76  customParameters.insert(ParametersPair(Parameters::kMemMapLabelsAdded(), "false")); // don't create map labels
77  customParameters.insert(ParametersPair(Parameters::kMemBadSignaturesIgnored(), "true")); // make sure memory cleanup is done
78  customParameters.insert(ParametersPair(Parameters::kMemIntermediateNodeDataKept(), "true"));
79  if(!recordInRAM)
80  {
81  customParameters.insert(ParametersPair(Parameters::kDbSqlite3InMemory(), "false"));
82  }
83  memory_ = new Memory();
84  if(!memory_->init(path.toStdString(), true, customParameters))
85  {
86  delete memory_;
87  memory_ = 0;
88  UERROR("Error initializing the memory.");
89  return false;
90  }
91  path_ = path;
92  return true;
93  }
94  else
95  {
96  UERROR("Already initialized, close it first.");
97  return false;
98  }
99 }
100 
102 {
103  memoryMutex_.lock();
104  if(memory_)
105  {
106  delete memory_;
107  memory_ = 0;
108  UINFO("Data recorded to \"%s\".", this->path().toStdString().c_str());
109  }
111  processingImages_ = false;
112  count_ = 0;
113  totalSizeKB_ = 0;
114  if(this->isVisible())
115  {
116  QMessageBox::information(this, tr("Data recorder"), tr("Data recorded to \"%1\".").arg(this->path()));
117  }
118 }
119 
121 {
123  this->closeRecorder();
124 }
125 
126 void DataRecorder::addData(const rtabmap::SensorData & data, const Transform & pose, const cv::Mat & covariance)
127 {
128  memoryMutex_.lock();
129  if(memory_)
130  {
131  if(memory_->getStMem().size() == 0 && data.id() > 0)
132  {
133  ParametersMap customParameters;
134  customParameters.insert(ParametersPair(Parameters::kMemGenerateIds(), "false")); // use id from data
135  memory_->parseParameters(customParameters);
136  }
137 
138  //save to database
139  UTimer time;
140  memory_->update(data, pose, covariance);
142  totalSizeKB_ += (int)s->sensorData().imageCompressed().total()/1000;
143  totalSizeKB_ += (int)s->sensorData().depthOrRightCompressed().total()/1000;
144  totalSizeKB_ += (int)s->sensorData().laserScanCompressed().data().total()/1000;
145  memory_->cleanup();
146 
147  if(++count_ % 30)
148  {
149  memory_->emptyTrash();
150  }
151  UDEBUG("Time to process a message = %f s, totalSizeKB_=%d", time.ticks(), totalSizeKB_);
152  }
154 }
155 
156 void DataRecorder::showImage(const cv::Mat & image, const cv::Mat & depth)
157 {
158  processingImages_ = true;
160  imageView_->setImageDepth(depth);
161  label_->setText(tr("Images=%1 (~%2 MB)").arg(count_).arg(totalSizeKB_/1000));
162  processingImages_ = false;
163 }
164 
165 void DataRecorder::closeEvent(QCloseEvent* event)
166 {
167  this->closeRecorder();
168  event->accept();
169 }
170 
172 {
173  if(memory_)
174  {
175  if(event->getClassName().compare("CameraEvent") == 0)
176  {
177  CameraEvent * camEvent = (CameraEvent*)event;
178  if(camEvent->getCode() == CameraEvent::kCodeData)
179  {
180  if(camEvent->data().isValid())
181  {
182  UINFO("Receiving rate = %f Hz", 1.0f/timer_.ticks());
183  this->addData(
184  camEvent->data(),
185  camEvent->info().odomPose,
186  camEvent->info().odomCovariance.empty()?cv::Mat::eye(6,6,CV_64FC1):camEvent->info().odomCovariance);
187 
188  if(!processingImages_ && this->isVisible() && camEvent->data().isValid())
189  {
190  processingImages_ = true;
191  QMetaObject::invokeMethod(this, "showImage",
192  Q_ARG(cv::Mat, camEvent->data().imageRaw()),
193  Q_ARG(cv::Mat, camEvent->data().depthOrRightRaw()));
194  }
195  }
196  }
197  }
198  }
199  return false;
200 }
201 
202 } /* namespace rtabmap */
int getCode() const
Definition: UEvent.h:74
bool handleEvent(UEvent *event)
cv::Mat odomCovariance
Definition: CameraInfo.h:69
Definition: UTimer.h:46
DataRecorder(QWidget *parent=0)
const cv::Mat & data() const
Definition: LaserScan.h:63
Definition: UEvent.h:57
const LaserScan & laserScanCompressed() const
Definition: SensorData.h:159
int lock() const
Definition: UMutex.h:87
f
void showImage(const cv::Mat &image, const cv::Mat &depth)
virtual void closeEvent(QCloseEvent *event)
std::pair< std::string, std::string > ParametersPair
Definition: Parameters.h:42
void addData(const rtabmap::SensorData &data, const Transform &pose=Transform(), const cv::Mat &infMatrix=cv::Mat::eye(6, 6, CV_64FC1))
std::map< std::string, std::string > ParametersMap
Definition: Parameters.h:41
ImageView * imageView_
Definition: DataRecorder.h:69
const QString & path() const
Definition: DataRecorder.h:57
void setImage(const QImage &image)
Definition: ImageView.cpp:871
const cv::Mat & imageRaw() const
Definition: SensorData.h:161
const std::set< int > & getStMem() const
Definition: Memory.h:147
bool init(const std::string &dbUrl, bool dbOverwritten=false, const ParametersMap &parameters=ParametersMap(), bool postInitClosingEvents=false)
Definition: Memory.cpp:142
bool isValid() const
Definition: SensorData.h:134
const cv::Mat & depthOrRightCompressed() const
Definition: SensorData.h:158
QImage uCvMat2QImage(const cv::Mat &image, bool isBgr=true, uCvQtDepthColorMap colorMap=uCvQtDepthWhiteToBlack)
Definition: UCv2Qt.h:44
virtual std::string getClassName() const =0
void setImageDepth(const cv::Mat &imageDepth)
Definition: ImageView.cpp:898
bool update(const SensorData &data, Statistics *stats=0)
Definition: Memory.cpp:663
void emptyTrash()
Definition: Memory.cpp:1866
const cv::Mat & depthOrRightRaw() const
Definition: SensorData.h:162
int id() const
Definition: SensorData.h:152
#define false
Definition: ConvertUTF.c:56
virtual void parseParameters(const ParametersMap &parameters)
Definition: Memory.cpp:442
#define UDEBUG(...)
SensorData & sensorData()
Definition: Signature.h:134
const CameraInfo & info() const
Definition: CameraEvent.h:81
const Signature * getLastWorkingSignature() const
Definition: Memory.cpp:2165
int unlock() const
Definition: UMutex.h:113
#define UERROR(...)
ULogger class and convenient macros.
double ticks()
Definition: UTimer.cpp:110
const cv::Mat & imageCompressed() const
Definition: SensorData.h:157
bool init(const QString &path, bool recordInRAM=true)
const SensorData & data() const
Definition: CameraEvent.h:79
void unregisterFromEventsManager()
Transform odomPose
Definition: CameraInfo.h:68
void setImageDepthShown(bool shown)
Definition: ImageView.cpp:356
#define UINFO(...)


rtabmap
Author(s): Mathieu Labbe
autogenerated on Wed Jun 5 2019 22:41:31