OdometryThread.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 #include "rtabmap/core/Odometry.h"
35 
36 namespace rtabmap {
37 
38 OdometryThread::OdometryThread(Odometry * odometry, unsigned int dataBufferMaxSize) :
39  _odometry(odometry),
40  _dataBufferMaxSize(dataBufferMaxSize),
41  _resetOdometry(false),
42  _resetPose(Transform::getIdentity()),
43  _lastImuStamp(0.0),
44  _imuEstimatedDelay(0.0)
45 {
46  UASSERT(_odometry != 0);
47 }
48 
50 {
52  this->join(true);
53  delete _odometry;
54  UDEBUG("");
55 }
56 
58 {
59  if(this->isRunning())
60  {
61  if(event->getClassName().compare("CameraEvent") == 0)
62  {
63  CameraEvent * cameraEvent = (CameraEvent*)event;
64  if(cameraEvent->getCode() == CameraEvent::kCodeData)
65  {
66  this->addData(cameraEvent->data());
67  }
68  }
69  else if(event->getClassName().compare("IMUEvent") == 0)
70  {
71  IMUEvent * imuEvent = (IMUEvent*)event;
72  if(!imuEvent->getData().empty())
73  {
74  this->addData(SensorData(imuEvent->getData(), 0, imuEvent->getStamp()));
75  }
76  }
77  }
78  if(event->getClassName().compare("OdometryResetEvent") == 0)
79  {
80  OdometryResetEvent * odomEvent = (OdometryResetEvent*)event;
82  if(!odomEvent->getPose().isNull())
83  {
84  _resetPose = odomEvent->getPose();
85  }
86  _resetOdometry = true;
87  }
88  return false;
89 }
90 
92 {
94 }
95 
97 {
99 }
100 
101 //============================================================
102 // MAIN LOOP
103 //============================================================
105 {
106  if(_resetOdometry)
107  {
109  _resetOdometry = false;
110  UScopeMutex lock(_dataMutex);
111  _dataBuffer.clear();
112  _imuBuffer.clear();
113  _lastImuStamp = 0.0f;
114  }
115 
116  SensorData data;
117  if(getData(data))
118  {
119  OdometryInfo info;
120  UDEBUG("Processing data...");
121  Transform pose = _odometry->process(data, &info);
122  if(!data.imageRaw().empty() || (pose.isNull() && data.imu().empty()))
123  {
124  UDEBUG("Odom pose = %s", pose.prettyPrint().c_str());
125  // a null pose notify that odometry could not be computed
126  this->post(new OdometryEvent(data, pose, info));
127  }
128  }
129 }
130 
132 {
133  if(data.imu().empty())
134  {
135  if(dynamic_cast<OdometryMono*>(_odometry) == 0)
136  {
137  if(data.imageRaw().empty() || data.depthOrRightRaw().empty() || (data.cameraModels().size()==0 && !data.stereoCameraModel().isValidForProjection()))
138  {
139  ULOGGER_ERROR("Missing some information (images empty or missing calibration)!?");
140  return;
141  }
142  }
143  else
144  {
145  // Mono can accept RGB only
146  if(data.imageRaw().empty() || (data.cameraModels().size()==0 && !data.stereoCameraModel().isValidForProjection()))
147  {
148  ULOGGER_ERROR("Missing some information (image empty or missing calibration)!?");
149  return;
150  }
151  }
152  }
153 
154  bool notify = true;
155  _dataMutex.lock();
156  {
157  if(!data.imageRaw().empty() || !data.laserScanRaw().isEmpty() || data.imu().empty())
158  {
159  _dataBuffer.push_back(data);
160  while(_dataBufferMaxSize > 0 && _dataBuffer.size() > _dataBufferMaxSize)
161  {
162  UDEBUG("Data buffer is full, the oldest data is removed to add the new one.");
163  _dataBuffer.erase(_dataBuffer.begin());
164  notify = false;
165  }
166  }
167  else
168  {
169  _imuBuffer.push_back(data);
170  if(_lastImuStamp != 0.0 && data.stamp() > _lastImuStamp)
171  {
173  }
174  _lastImuStamp = data.stamp();
175  }
176  }
177  _dataMutex.unlock();
178 
179  if(notify)
180  {
182  }
183 }
184 
186 {
187  bool dataFilled = false;
189  _dataMutex.lock();
190  {
191  if(!_dataBuffer.empty())
192  {
193  while(!_imuBuffer.empty() && _imuBuffer.front().stamp() <= _dataBuffer.front().stamp())
194  {
195  _odometry->process(_imuBuffer.front());
196  _imuBuffer.pop_front();
197  }
198 
199  data = _dataBuffer.front();
200  _dataBuffer.pop_front();
201  dataFilled = true;
202  }
203  }
204  _dataMutex.unlock();
205  return dataFilled;
206 }
207 
208 } // namespace rtabmap
int getCode() const
Definition: UEvent.h:74
void release(int n=1)
Definition: USemaphore.h:168
std::string prettyPrint() const
Definition: Transform.cpp:295
Definition: UEvent.h:57
bool empty() const
Definition: IMU.h:63
int lock() const
Definition: UMutex.h:87
virtual void reset(const Transform &initialPose=Transform::getIdentity())
Definition: Odometry.cpp:191
bool isRunning() const
Definition: UThread.cpp:245
bool isEmpty() const
Definition: LaserScan.h:101
virtual void mainLoopBegin()
bool acquire(int n=1, int ms=0)
Definition: USemaphore.h:101
const LaserScan & laserScanRaw() const
Definition: SensorData.h:166
const cv::Mat & imageRaw() const
Definition: SensorData.h:164
void post(UEvent *event, bool async=true) const
Transform process(SensorData &data, OdometryInfo *info=0)
Definition: Odometry.cpp:278
virtual void mainLoopKill()
#define UASSERT(condition)
bool isNull() const
Definition: Transform.cpp:107
std::list< SensorData > _dataBuffer
virtual std::string getClassName() const =0
void addData(const SensorData &data)
static void registerCurrentThread(const std::string &name)
Definition: ULogger.cpp:218
const IMU & getData() const
Definition: IMU.h:93
const cv::Mat & depthOrRightRaw() const
Definition: SensorData.h:165
double stamp() const
Definition: SensorData.h:157
unsigned int _dataBufferMaxSize
#define false
Definition: ConvertUTF.c:56
const IMU & imu() const
Definition: SensorData.h:269
const std::vector< CameraModel > & cameraModels() const
Definition: SensorData.h:215
const Transform & getPose() const
#define UDEBUG(...)
int unlock() const
Definition: UMutex.h:113
double getStamp() const
Definition: IMU.h:94
ULogger class and convenient macros.
const StereoCameraModel & stereoCameraModel() const
Definition: SensorData.h:216
bool getData(SensorData &data)
const SensorData & data() const
Definition: CameraEvent.h:79
void unregisterFromEventsManager()
void join(bool killFirst=false)
Definition: UThread.cpp:85
virtual bool handleEvent(UEvent *event)
#define ULOGGER_ERROR(...)
Definition: ULogger.h:56
OdometryThread(Odometry *odometry, unsigned int dataBufferMaxSize=1)
std::list< SensorData > _imuBuffer


rtabmap
Author(s): Mathieu Labbe
autogenerated on Mon Dec 14 2020 03:34:59