50 #include <pcl/pcl_base.h> 56 int odomTypeInt = Parameters::defaultOdomStrategy();
59 return create(type, parameters);
64 UDEBUG(
"type=%d", (
int)type);
99 UERROR(
"Unknown odometry type %d, using F2M instead...", (
int)type);
210 if(z != 0.0
f || roll != 0.0
f || pitch != 0.0
f)
212 UWARN(
"Force2D=true and the initial pose contains z, roll or pitch values (%s). They are set to null.", initialPose.
prettyPrint().c_str());
217 Transform pose(x, y, z, roll, pitch, yaw);
247 const Transform & Odometry::previousVelocityTransform()
const 254 if(transforms.size())
256 float tvx=0.0f,tvy=0.0f,tvz=0.0f, tvroll=0.0f,tvpitch=0.0f,tvyaw=0.0f;
257 for(std::list<std::pair<std::vector<float>,
double> >::const_iterator iter=transforms.begin(); iter!=transforms.end(); ++iter)
259 UASSERT(iter->first.size() == 6);
263 tvroll+=iter->first[3];
264 tvpitch+=iter->first[4];
265 tvyaw+=iter->first[5];
267 tvx/=float(transforms.size());
268 tvy/=float(transforms.size());
269 tvz/=float(transforms.size());
270 tvroll/=float(transforms.size());
271 tvpitch/=float(transforms.size());
272 tvyaw/=float(transforms.size());
273 return Transform(tvx, tvy, tvz, tvroll, tvpitch, tvyaw);
285 UASSERT_MSG(data.
id() >= 0,
uFormat(
"Input data should have ID greater or equal than 0 (id=%d)!", data.
id()).c_str());
298 UWARN(
"%s parameter is set to false but the selected odometry approach cannot " 299 "process raw images. We will rectify them for convenience.",
300 Parameters::kRtabmapImagesAlreadyRectified().c_str());
304 UERROR(
"Odometry approach chosen cannot process raw images (not rectified images) and we cannot rectify them. " 305 "Make sure images are rectified, and set %s parameter back to true.",
306 Parameters::kRtabmapImagesAlreadyRectified().c_str());
320 UERROR(
"Odometry approach chosen cannot process raw images (not rectified images). Make sure images " 321 "are rectified, and set %s parameter back to true.",
322 Parameters::kRtabmapImagesAlreadyRectified().c_str());
331 UWARN(
"\"%s\" is true but the input has no depth information, ignoring alignment with ground...", Parameters::kOdomAlignWithGround().c_str());
336 pcl::IndicesPtr indices(
new std::vector<int>);
337 pcl::IndicesPtr ground, obstacles;
339 bool success =
false;
343 util3d::segmentObstaclesFromGround<pcl::PointXYZ>(cloud, ground, obstacles, 20,
M_PI/4.0f, 0.02, 200,
true);
346 pcl::ModelCoefficients coefficients;
348 if(coefficients.values.at(3) >= 0)
350 UWARN(
"Ground detected! coefficients=(%f, %f, %f, %f) time=%fs",
351 coefficients.values.at(0),
352 coefficients.values.at(1),
353 coefficients.values.at(2),
354 coefficients.values.at(3),
359 UWARN(
"Ceiling detected! coefficients=(%f, %f, %f, %f) time=%fs",
360 coefficients.values.at(0),
361 coefficients.values.at(1),
362 coefficients.values.at(2),
363 coefficients.values.at(3),
366 Eigen::Vector3f n(coefficients.values.at(0), coefficients.values.at(1), coefficients.values.at(2));
367 Eigen::Vector3f z(0,0,1);
370 R = Eigen::Quaternionf().setFromTwoVectors(n,z);
372 R(0,0), R(0,1), R(0,2), 0,
373 R(1,0), R(1,1), R(1,2), 0,
374 R(2,0), R(2,1), R(2,2), coefficients.values.at(3));
381 UERROR(
"Odometry failed to detect the ground. You have this " 382 "error because parameter \"%s\" is true. " 383 "Make sure the camera is seeing the ground (e.g., tilt ~30 " 384 "degrees toward the ground).", Parameters::kOdomAlignWithGround().c_str());
397 if(
imus_.size() > 1000)
411 UERROR(
"Guess from motion is set but dt is invalid! Odometry is then computed without guess. (dt=%f previous transform=%s)", dt,
velocityGuess_.
prettyPrint().c_str());
415 UERROR(
"Kalman filtering is enabled but dt is invalid! Odometry is then computed without Kalman filtering. (dt=%f previous transform=%s)", dt,
velocityGuess_.
prettyPrint().c_str());
428 float vx,vy,vz, vroll,vpitch,vyaw;
430 guess =
Transform(vx*dt, vy*dt, vz*dt, vroll*dt, vpitch*dt, vyaw*dt);
434 float vx,vy,vz, vroll,vpitch,vyaw;
436 guess =
Transform(vx*dt, vy*dt, vz*dt, vroll*dt, vpitch*dt, vyaw*dt);
458 orientation.
r11(), orientation.
r12(), orientation.
r13(), guess.
x(),
459 orientation.
r21(), orientation.
r22(), orientation.
r23(), guess.
y(),
460 orientation.
r31(), orientation.
r32(), orientation.
r33(), guess.
z());
472 std::vector<CameraModel> cameraModels = decimatedData.
cameraModels();
473 for(
unsigned int i=0; i<cameraModels.size(); ++i)
477 if(!cameraModels.empty())
479 decimatedData.
setRGBDImage(rgbLeft, depthRight, cameraModels);
496 std::vector<cv::KeyPoint> kpts = decimatedData.
keypoints();
498 for(
unsigned int i=0; i<kpts.size(); ++i)
503 kpts[i].octave += log2value;
510 for(
unsigned int i=0; i<info->
newCorners.size(); ++i)
517 for(std::multimap<int, cv::KeyPoint>::iterator iter=info->
words.begin(); iter!=info->
words.end(); ++iter)
522 iter->second.octave += log2value;
562 float vx,vy,vz, vroll,vpitch,vyaw;
622 float tmpY = vyaw!=0.0f ? vx /
tan((CV_PI-vyaw)/2.0
f) : 0.0f;
623 if(fabs(tmpY) < fabs(vy) || (tmpY<=0 && vy >=0) || (tmpY>=0 && vy<=0))
629 vyaw = (
atan(vx/vy)*2.0f-CV_PI)*-1;
649 vy = vyaw!=0.0f ? vx /
tan((CV_PI-vyaw)/2.0
f) : 0.0f;
662 t =
Transform(vx*dt, vy*dt, vz*dt, vroll*dt, vpitch*dt, vyaw*dt);
666 t =
Transform(vx, vy, vz, vroll, vpitch, vyaw);
677 UWARN(
"Null stamp detected");
692 std::vector<float> v(6);
727 UWARN(
"Odometry lost! Odometry will be reset after next %d consecutive unsuccessful odometry updates...",
_resetCurrentCount);
732 UWARN(
"Odometry automatically reset to latest pose!");
752 int nMeasurements = 6;
909 *vx = prediction.at<
float>(3);
911 *vy = prediction.at<
float>(4);
913 *vz =
_force3DoF?0.0f:prediction.at<
float>(5);
915 *vroll =
_force3DoF?0.0f:prediction.at<
float>(12);
917 *vpitch =
_force3DoF?0.0f:prediction.at<
float>(13);
919 *vyaw = prediction.at<
float>(
_force3DoF?7:14);
925 cv::Mat measurements;
928 measurements = cv::Mat(6,1,CV_32FC1);
929 measurements.at<
float>(0) = vx;
930 measurements.at<
float>(1) = vy;
931 measurements.at<
float>(2) = vz;
932 measurements.at<
float>(3) = vroll;
933 measurements.at<
float>(4) = vpitch;
934 measurements.at<
float>(5) = vyaw;
938 measurements = cv::Mat(3,1,CV_32FC1);
939 measurements.at<
float>(0) = vx;
940 measurements.at<
float>(1) = vy;
941 measurements.at<
float>(2) = vyaw;
946 const cv::Mat & estimated =
kalmanFilter_.correct(measurements);
949 vx = estimated.at<
float>(3);
950 vy = estimated.at<
float>(4);
952 vroll =
_force3DoF?0.0f:estimated.at<
float>(12);
953 vpitch =
_force3DoF?0.0f:estimated.at<
float>(13);
GLM_FUNC_DECL genType log(genType const &x)
GLM_FUNC_DECL T roll(detail::tquat< T, P > const &x)
static bool parse(const ParametersMap ¶meters, const std::string &key, bool &value)
bool _imagesAlreadyRectified
std::vector< cv::Point2f > refCorners
unsigned int framesProcessed() const
float _kalmanMeasurementNoise
Transform transformGroundTruth
const cv::Vec4d & orientation() const
const cv::Size & imageSize() const
cv::KalmanFilter kalmanFilter_
virtual void reset(const Transform &initialPose=Transform::getIdentity())
Transform transformFiltered
bool isRectificationMapInitialized() const
unsigned int framesProcessed_
const cv::Mat & descriptors() const
GLM_FUNC_DECL bool all(vecType< bool, P > const &v)
void setRGBDImage(const cv::Mat &rgb, const cv::Mat &depth, const CameraModel &model, bool clearPreviousData=true)
std::map< std::string, std::string > ParametersMap
float _kalmanProcessNoise
float timeParticleFiltering
const std::vector< cv::KeyPoint > & keypoints() const
Some conversion functions.
virtual bool canProcessRawImages() const
const LaserScan & laserScanRaw() const
GLM_FUNC_DECL T pitch(detail::tquat< T, P > const &x)
float guessSmoothingDelay_
const Transform & groundTruth() const
const cv::Mat & imageRaw() const
void initRectificationMap()
void predictKalmanFilter(float dt, float *vx=0, float *vy=0, float *vz=0, float *vroll=0, float *vpitch=0, float *vyaw=0)
Transform process(SensorData &data, OdometryInfo *info=0)
StereoCameraModel stereoModel_
#define UASSERT(condition)
bool isValidForProjection() const
void updateKalmanFilter(float &vx, float &vy, float &vz, float &vroll, float &vpitch, float &vyaw)
const CameraModel & left() const
static Odometry * create(const ParametersMap ¶meters=ParametersMap())
#define UASSERT_MSG(condition, msg_str)
cv::Mat RTABMAP_EXP decimate(const cv::Mat &image, int d)
GLM_FUNC_DECL genType atan(genType const &y, genType const &x)
Transform previousGroundTruthPose_
virtual Transform computeTransform(SensorData &data, const Transform &guess=Transform(), OdometryInfo *info=0)=0
void setStereoImage(const cv::Mat &left, const cv::Mat &right, const StereoCameraModel &stereoCameraModel, bool clearPreviousData=true)
const cv::Mat & depthOrRightRaw() const
std::vector< ParticleFilter * > particleFilters_
GLM_FUNC_DECL detail::tquat< T, P > rotation(detail::tvec3< T, P > const &orig, detail::tvec3< T, P > const &dest)
cv::Mat rectifyImage(const cv::Mat &raw, int interpolation=cv::INTER_LINEAR) const
Transform getMeanVelocity(const std::list< std::pair< std::vector< float >, double > > &transforms)
const Transform & getVelocityGuess() const
GLM_FUNC_DECL genType tan(genType const &angle)
const std::vector< CameraModel > & cameraModels() const
pcl::PointCloud< pcl::PointXYZ >::Ptr RTABMAP_EXP cloudFromSensorData(const SensorData &sensorData, int decimation=1, float maxDepth=0.0f, float minDepth=0.0f, std::vector< int > *validIndices=0, const ParametersMap &stereoParameters=ParametersMap(), const std::vector< float > &roiRatios=std::vector< float >())
const Transform & localTransform() const
std::multimap< int, cv::KeyPoint > words
GLM_FUNC_DECL genType pow(genType const &base, genType const &exponent)
bool isValidForRectification() const
const CameraModel & right() const
pcl::IndicesPtr extractPlane(const pcl::PointCloud< pcl::PointXYZ >::Ptr &cloud, float distanceThreshold, int maxIterations=100, pcl::ModelCoefficients *coefficientsOut=0)
static long int getMemoryUsage()
ULogger class and convenient macros.
const StereoCameraModel & stereoCameraModel() const
GLM_FUNC_DECL T yaw(detail::tquat< T, P > const &x)
std::vector< cv::Point2f > newCorners
Odometry(const rtabmap::ParametersMap ¶meters)
pcl::PointCloud< pcl::PointXYZ >::Ptr RTABMAP_EXP voxelize(const pcl::PointCloud< pcl::PointXYZ >::Ptr &cloud, const pcl::IndicesPtr &indices, float voxelSize)
Transform imuLastTransform_
std::map< double, Transform > imus_
std::list< std::pair< std::vector< float >, double > > previousVelocities_
std::string UTILITE_EXP uFormat(const char *fmt,...)
void setFeatures(const std::vector< cv::KeyPoint > &keypoints, const std::vector< cv::Point3f > &keypoints3D, const cv::Mat &descriptors)
const std::vector< cv::Point3f > & keypoints3D() const
GLM_FUNC_DECL detail::tmat4x4< T, P > orientation(detail::tvec3< T, P > const &Normal, detail::tvec3< T, P > const &Up)
void initKalmanFilter(const Transform &initialPose=Transform::getIdentity(), float vx=0.0f, float vy=0.0f, float vz=0.0f, float vroll=0.0f, float vpitch=0.0f, float vyaw=0.0f)