mirror of
https://github.com/introlab/rtabmap.git
synced 2026-10-04 09:07:47 +08:00
Added CameraStereoImages class to read stereo images from a directory. Added a particle filter to smooth odometry trajectory. Added parameter RGBD/OptimizeEpsilon to limit TORO iterations when error improvement is small. Added Rtabmap/CreateIntermediateNodes parameter: this can be used to keep all odometry poses 'between' nodes used for loop closure detection. Added PnP approach to loop closure constraint estimation. Fixed decimation of stereo images when image size is odd.
This commit is contained in:
+103
-9
@@ -29,6 +29,7 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
#include "rtabmap/core/OdometryInfo.h"
|
||||
#include "rtabmap/utilite/ULogger.h"
|
||||
#include "rtabmap/utilite/UTimer.h"
|
||||
#include "ParticleFilter.h"
|
||||
|
||||
namespace rtabmap {
|
||||
|
||||
@@ -41,11 +42,18 @@ Odometry::Odometry(const rtabmap::ParametersMap & parameters) :
|
||||
_maxDepth(Parameters::defaultOdomMaxDepth()),
|
||||
_resetCountdown(Parameters::defaultOdomResetCountdown()),
|
||||
_force2D(Parameters::defaultOdomForce2D()),
|
||||
_particleFiltering(Parameters::defaultOdomParticleFiltering()),
|
||||
_particleSize(Parameters::defaultOdomParticleSize()),
|
||||
_particleNoiseT(Parameters::defaultOdomParticleNoiseT()),
|
||||
_particleLambdaT(Parameters::defaultOdomParticleLambdaT()),
|
||||
_particleNoiseR(Parameters::defaultOdomParticleNoiseR()),
|
||||
_particleLambdaR(Parameters::defaultOdomParticleLambdaR()),
|
||||
_fillInfoData(Parameters::defaultOdomFillInfoData()),
|
||||
_pnpEstimation(Parameters::defaultOdomPnPEstimation()),
|
||||
_pnpReprojError(Parameters::defaultOdomPnPReprojError()),
|
||||
_pnpFlags(Parameters::defaultOdomPnPFlags()),
|
||||
_resetCurrentCount(0)
|
||||
_resetCurrentCount(0),
|
||||
previousStamp_(0)
|
||||
{
|
||||
Parameters::parse(parameters, Parameters::kOdomResetCountdown(), _resetCountdown);
|
||||
Parameters::parse(parameters, Parameters::kOdomMinInliers(), _minInliers);
|
||||
@@ -60,21 +68,78 @@ Odometry::Odometry(const rtabmap::ParametersMap & parameters) :
|
||||
Parameters::parse(parameters, Parameters::kOdomPnPReprojError(), _pnpReprojError);
|
||||
Parameters::parse(parameters, Parameters::kOdomPnPFlags(), _pnpFlags);
|
||||
UASSERT(_pnpFlags>=0 && _pnpFlags <=2);
|
||||
Parameters::parse(parameters, Parameters::kOdomParticleFiltering(), _particleFiltering);
|
||||
Parameters::parse(parameters, Parameters::kOdomParticleSize(), _particleSize);
|
||||
Parameters::parse(parameters, Parameters::kOdomParticleNoiseT(), _particleNoiseT);
|
||||
Parameters::parse(parameters, Parameters::kOdomParticleLambdaT(), _particleLambdaT);
|
||||
Parameters::parse(parameters, Parameters::kOdomParticleNoiseR(), _particleNoiseR);
|
||||
Parameters::parse(parameters, Parameters::kOdomParticleLambdaR(), _particleLambdaR);
|
||||
UASSERT(_particleNoiseT>0);
|
||||
UASSERT(_particleLambdaT>0);
|
||||
UASSERT(_particleNoiseR>0);
|
||||
UASSERT(_particleLambdaR>0);
|
||||
if(_particleFiltering)
|
||||
{
|
||||
filters_.resize(6);
|
||||
for(unsigned int i = 0; i<filters_.size(); ++i)
|
||||
{
|
||||
if(i<3)
|
||||
{
|
||||
filters_[i] = new ParticleFilter(_particleSize, _particleNoiseT, _particleLambdaT);
|
||||
}
|
||||
else
|
||||
{
|
||||
filters_[i] = new ParticleFilter(_particleSize, _particleNoiseR, _particleLambdaR);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Odometry::~Odometry()
|
||||
{
|
||||
for(unsigned int i=0; i<filters_.size(); ++i)
|
||||
{
|
||||
delete filters_[i];
|
||||
}
|
||||
filters_.clear();
|
||||
}
|
||||
|
||||
void Odometry::reset(const Transform & initialPose)
|
||||
{
|
||||
_resetCurrentCount = 0;
|
||||
if(_force2D)
|
||||
previousStamp_ = 0;
|
||||
if(_force2D || filters_.size())
|
||||
{
|
||||
float x,y,z, roll,pitch,yaw;
|
||||
initialPose.getTranslationAndEulerAngles(x, y, z, roll, pitch, yaw);
|
||||
if(z != 0.0f || roll != 0.0f || yaw != 0.0f)
|
||||
|
||||
if(_force2D)
|
||||
{
|
||||
UWARN("Force2D=true and the initial pose contains z, roll or pitch values (%s). They are set to null.", initialPose.prettyPrint().c_str());
|
||||
if(z != 0.0f || roll != 0.0f || yaw != 0.0f)
|
||||
{
|
||||
UWARN("Force2D=true and the initial pose contains z, roll or pitch values (%s). They are set to null.", initialPose.prettyPrint().c_str());
|
||||
}
|
||||
z = 0;
|
||||
roll = 0;
|
||||
yaw = 0;
|
||||
Transform pose(x, y, z, roll, pitch, yaw);
|
||||
_pose = pose;
|
||||
}
|
||||
else
|
||||
{
|
||||
_pose = initialPose;
|
||||
}
|
||||
|
||||
if(filters_.size())
|
||||
{
|
||||
UASSERT(filters_.size() == 6);
|
||||
filters_[0]->init(x);
|
||||
filters_[1]->init(y);
|
||||
filters_[2]->init(z);
|
||||
filters_[3]->init(roll);
|
||||
filters_[4]->init(pitch);
|
||||
filters_[5]->init(yaw);
|
||||
}
|
||||
Transform pose(x, y, 0, 0, 0, yaw);
|
||||
_pose = pose;
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -107,19 +172,48 @@ Transform Odometry::process(const SensorData & data, OdometryInfo * info)
|
||||
|
||||
if(info)
|
||||
{
|
||||
info->time = time.elapsed();
|
||||
info->timeEstimation = time.ticks();
|
||||
info->lost = t.isNull();
|
||||
info->stamp = data.stamp();
|
||||
info->interval = data.stamp() - previousStamp_;
|
||||
info->transform = t;
|
||||
}
|
||||
previousStamp_ = data.stamp();
|
||||
|
||||
if(!t.isNull())
|
||||
{
|
||||
_resetCurrentCount = _resetCountdown;
|
||||
|
||||
if(_force2D)
|
||||
if(_force2D || filters_.size())
|
||||
{
|
||||
float x,y,z, roll,pitch,yaw;
|
||||
t.getTranslationAndEulerAngles(x, y, z, roll, pitch, yaw);
|
||||
t = Transform(x,y,0, 0,0,yaw);
|
||||
|
||||
if(filters_.size())
|
||||
{
|
||||
UASSERT(filters_.size()==6);
|
||||
x = filters_[0]->filter(x);
|
||||
y = filters_[1]->filter(y);
|
||||
yaw = filters_[5]->filter(yaw);
|
||||
|
||||
if(!_force2D)
|
||||
{
|
||||
z = filters_[2]->filter(z);
|
||||
roll = filters_[3]->filter(roll);
|
||||
pitch = filters_[4]->filter(pitch);
|
||||
}
|
||||
|
||||
if(info)
|
||||
{
|
||||
info->timeParticleFiltering = time.ticks();
|
||||
}
|
||||
}
|
||||
t = Transform(x,y,_force2D?0:z, _force2D?0:roll,_force2D?0:pitch,yaw);
|
||||
|
||||
if(info)
|
||||
{
|
||||
info->transformFiltered = t;
|
||||
}
|
||||
}
|
||||
|
||||
return _pose *= t; // updated
|
||||
|
||||
Reference in New Issue
Block a user