00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028 #include "rtabmap/core/Odometry.h"
00029 #include "rtabmap/core/OdometryInfo.h"
00030 #include "rtabmap/utilite/ULogger.h"
00031 #include "rtabmap/utilite/UTimer.h"
00032
00033 namespace rtabmap {
00034
00035 Odometry::Odometry(const rtabmap::ParametersMap & parameters) :
00036 _roiRatios(Parameters::defaultOdomRoiRatios()),
00037 _minInliers(Parameters::defaultOdomMinInliers()),
00038 _inlierDistance(Parameters::defaultOdomInlierDistance()),
00039 _iterations(Parameters::defaultOdomIterations()),
00040 _refineIterations(Parameters::defaultOdomRefineIterations()),
00041 _maxDepth(Parameters::defaultOdomMaxDepth()),
00042 _resetCountdown(Parameters::defaultOdomResetCountdown()),
00043 _force2D(Parameters::defaultOdomForce2D()),
00044 _fillInfoData(Parameters::defaultOdomFillInfoData()),
00045 _pnpEstimation(Parameters::defaultOdomPnPEstimation()),
00046 _pnpReprojError(Parameters::defaultOdomPnPReprojError()),
00047 _pnpFlags(Parameters::defaultOdomPnPFlags()),
00048 _resetCurrentCount(0)
00049 {
00050 Parameters::parse(parameters, Parameters::kOdomResetCountdown(), _resetCountdown);
00051 Parameters::parse(parameters, Parameters::kOdomMinInliers(), _minInliers);
00052 Parameters::parse(parameters, Parameters::kOdomInlierDistance(), _inlierDistance);
00053 Parameters::parse(parameters, Parameters::kOdomIterations(), _iterations);
00054 Parameters::parse(parameters, Parameters::kOdomRefineIterations(), _refineIterations);
00055 Parameters::parse(parameters, Parameters::kOdomMaxDepth(), _maxDepth);
00056 Parameters::parse(parameters, Parameters::kOdomRoiRatios(), _roiRatios);
00057 Parameters::parse(parameters, Parameters::kOdomForce2D(), _force2D);
00058 Parameters::parse(parameters, Parameters::kOdomFillInfoData(), _fillInfoData);
00059 Parameters::parse(parameters, Parameters::kOdomPnPEstimation(), _pnpEstimation);
00060 Parameters::parse(parameters, Parameters::kOdomPnPReprojError(), _pnpReprojError);
00061 Parameters::parse(parameters, Parameters::kOdomPnPFlags(), _pnpFlags);
00062 UASSERT(_pnpFlags>=0 && _pnpFlags <=2);
00063 }
00064
00065 void Odometry::reset(const Transform & initialPose)
00066 {
00067 _resetCurrentCount = 0;
00068 if(_force2D)
00069 {
00070 float x,y,z, roll,pitch,yaw;
00071 initialPose.getTranslationAndEulerAngles(x, y, z, roll, pitch, yaw);
00072 if(z != 0.0f || roll != 0.0f || yaw != 0.0f)
00073 {
00074 UWARN("Force2D=true and the initial pose contains z, roll or pitch values (%s). They are set to null.", initialPose.prettyPrint().c_str());
00075 }
00076 Transform pose(x, y, 0, 0, 0, yaw);
00077 _pose = pose;
00078 }
00079 else
00080 {
00081 _pose = initialPose;
00082 }
00083 }
00084
00085 Transform Odometry::process(const SensorData & data, OdometryInfo * info)
00086 {
00087 if(_pose.isNull())
00088 {
00089 _pose.setIdentity();
00090 }
00091
00092 UASSERT(!data.image().empty());
00093 if(dynamic_cast<OdometryMono*>(this) == 0)
00094 {
00095 UASSERT(!data.depthOrRightImage().empty());
00096 }
00097
00098 if(data.fx() <= 0 || data.fyOrBaseline() <= 0)
00099 {
00100 UERROR("Rectified images required! Calibrate your camera. (fx=%f, fy/baseline=%f, cx=%f, cy=%f)",
00101 data.fx(), data.fyOrBaseline(), data.cx(), data.cy());
00102 return Transform();
00103 }
00104
00105 UTimer time;
00106 Transform t = this->computeTransform(data, info);
00107
00108 if(info)
00109 {
00110 info->time = time.elapsed();
00111 info->lost = t.isNull();
00112 }
00113
00114 if(!t.isNull())
00115 {
00116 _resetCurrentCount = _resetCountdown;
00117
00118 if(_force2D)
00119 {
00120 float x,y,z, roll,pitch,yaw;
00121 t.getTranslationAndEulerAngles(x, y, z, roll, pitch, yaw);
00122 t = Transform(x,y,0, 0,0,yaw);
00123 }
00124
00125 return _pose *= t;
00126 }
00127 else if(_resetCurrentCount > 0)
00128 {
00129 UWARN("Odometry lost! Odometry will be reset after next %d consecutive unsuccessful odometry updates...", _resetCurrentCount);
00130
00131 --_resetCurrentCount;
00132 if(_resetCurrentCount == 0)
00133 {
00134 UWARN("Odometry automatically reset to latest pose!");
00135 this->reset(_pose);
00136 }
00137 }
00138
00139 return Transform();
00140 }
00141
00142 }