49 #include <pcl/pcl_base.h> 55 int odomTypeInt = Parameters::defaultOdomStrategy();
58 return create(type, parameters);
63 UDEBUG(
"type=%d", (
int)type);
198 if(z != 0.0
f || roll != 0.0
f || pitch != 0.0
f)
200 UWARN(
"Force2D=true and the initial pose contains z, roll or pitch values (%s). They are set to null.", initialPose.
prettyPrint().c_str());
205 Transform pose(x, y, z, roll, pitch, yaw);
242 UASSERT_MSG(data.
id() >= 0,
uFormat(
"Input data should have ID greater or equal than 0 (id=%d)!", data.
id()).c_str());
246 UERROR(
"Odometry approach chosen cannot process raw images (not rectified images). Make sure images " 247 "are rectified, and set %s parameter back to true.",
248 Parameters::kRtabmapImagesAlreadyRectified().c_str());
256 UWARN(
"\"%s\" is true but the input has no depth information, ignoring alignment with ground...", Parameters::kOdomAlignWithGround().c_str());
261 pcl::IndicesPtr indices(
new std::vector<int>);
262 pcl::IndicesPtr ground, obstacles;
264 bool success =
false;
268 util3d::segmentObstaclesFromGround<pcl::PointXYZ>(cloud, ground, obstacles, 20,
M_PI/4.0f, 0.02, 200,
true);
271 pcl::ModelCoefficients coefficients;
273 if(coefficients.values.at(3) >= 0)
275 UWARN(
"Ground detected! coefficients=(%f, %f, %f, %f) time=%fs",
276 coefficients.values.at(0),
277 coefficients.values.at(1),
278 coefficients.values.at(2),
279 coefficients.values.at(3),
284 UWARN(
"Ceiling detected! coefficients=(%f, %f, %f, %f) time=%fs",
285 coefficients.values.at(0),
286 coefficients.values.at(1),
287 coefficients.values.at(2),
288 coefficients.values.at(3),
291 Eigen::Vector3f n(coefficients.values.at(0), coefficients.values.at(1), coefficients.values.at(2));
292 Eigen::Vector3f z(0,0,1);
295 R = Eigen::Quaternionf().setFromTwoVectors(n,z);
297 R(0,0), R(0,1), R(0,2), 0,
298 R(1,0), R(1,1), R(1,2), 0,
299 R(2,0), R(2,1), R(2,2), coefficients.values.at(3));
306 UERROR(
"Odometry failed to detect the ground. You have this " 307 "error because parameter \"%s\" is true. " 308 "Make sure the camera is seeing the ground (e.g., tilt ~30 " 309 "degrees toward the ground).", Parameters::kOdomAlignWithGround().c_str());
337 float vx,vy,vz, vroll,vpitch,vyaw;
339 guess =
Transform(vx*dt, vy*dt, vz*dt, vroll*dt, vpitch*dt, vyaw*dt);
343 float vx,vy,vz, vroll,vpitch,vyaw;
345 guess =
Transform(vx*dt, vy*dt, vz*dt, vroll*dt, vpitch*dt, vyaw*dt);
367 std::vector<CameraModel> cameraModels = decimatedData.
cameraModels();
368 for(
unsigned int i=0; i<cameraModels.size(); ++i)
384 std::vector<cv::KeyPoint> kpts = decimatedData.
keypoints();
386 for(
unsigned int i=0; i<kpts.size(); ++i)
391 kpts[i].octave += log2value;
398 for(
unsigned int i=0; i<info->
newCorners.size(); ++i)
405 for(std::multimap<int, cv::KeyPoint>::iterator iter=info->
words.begin(); iter!=info->
words.end(); ++iter)
410 iter->second.octave += log2value;
445 float vx,vy,vz, vroll,vpitch,vyaw;
503 float tmpY = vyaw!=0.0f ? vx /
tan((CV_PI-vyaw)/2.0
f) : 0.0f;
504 if(fabs(tmpY) < fabs(vy) || (tmpY<=0 && vy >=0) || (tmpY>=0 && vy<=0))
510 vyaw = (
atan(vx/vy)*2.0f-CV_PI)*-1;
537 vy = vyaw!=0.0f ? vx /
tan((CV_PI-vyaw)/2.0
f) : 0.0f;
548 t =
Transform(vx*dt, vy*dt, vz*dt, vroll*dt, vpitch*dt, vyaw*dt);
552 t =
Transform(vx, vy, vz, vroll, vpitch, vyaw);
563 UWARN(
"Null stamp detected");
585 UWARN(
"Odometry lost! Odometry will be reset after next %d consecutive unsuccessful odometry updates...",
_resetCurrentCount);
590 UWARN(
"Odometry automatically reset to latest pose!");
609 int nMeasurements = 6;
766 *vx = prediction.at<
float>(3);
768 *vy = prediction.at<
float>(4);
770 *vz =
_force3DoF?0.0f:prediction.at<
float>(5);
772 *vroll =
_force3DoF?0.0f:prediction.at<
float>(12);
774 *vpitch =
_force3DoF?0.0f:prediction.at<
float>(13);
776 *vyaw = prediction.at<
float>(
_force3DoF?7:14);
782 cv::Mat measurements;
785 measurements = cv::Mat(6,1,CV_32FC1);
786 measurements.at<
float>(0) = vx;
787 measurements.at<
float>(1) = vy;
788 measurements.at<
float>(2) = vz;
789 measurements.at<
float>(3) = vroll;
790 measurements.at<
float>(4) = vpitch;
791 measurements.at<
float>(5) = vyaw;
795 measurements = cv::Mat(3,1,CV_32FC1);
796 measurements.at<
float>(0) = vx;
797 measurements.at<
float>(1) = vy;
798 measurements.at<
float>(2) = vyaw;
803 const cv::Mat & estimated =
kalmanFilter_.correct(measurements);
806 vx = estimated.at<
float>(3);
807 vy = estimated.at<
float>(4);
809 vroll =
_force3DoF?0.0f:estimated.at<
float>(12);
810 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
cv::KalmanFilter kalmanFilter_
virtual void reset(const Transform &initialPose=Transform::getIdentity())
Transform transformFiltered
unsigned int framesProcessed_
Transform previousVelocityTransform_
const cv::Mat & descriptors() const
GLM_FUNC_DECL bool all(vecType< bool, P > const &v)
std::map< std::string, std::string > ParametersMap
float _kalmanProcessNoise
float timeParticleFiltering
const std::vector< cv::KeyPoint > & keypoints() const
void setCameraModels(const std::vector< CameraModel > &models)
Some conversion functions.
virtual bool canProcessRawImages() const
GLM_FUNC_DECL T pitch(detail::tquat< T, P > const &x)
const Transform & groundTruth() const
const cv::Mat & imageRaw() const
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)
void setImageRaw(const cv::Mat &imageRaw)
#define UASSERT(condition)
bool isValidForProjection() const
void updateKalmanFilter(float &vx, float &vy, float &vz, float &vroll, float &vpitch, float &vyaw)
#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
static Odometry * create(const ParametersMap ¶meters)
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)
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 >())
std::multimap< int, cv::KeyPoint > words
GLM_FUNC_DECL genType pow(genType const &base, genType const &exponent)
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)
void setStereoCameraModel(const StereoCameraModel &stereoCameraModel)
void setDepthOrRightRaw(const cv::Mat &depthOrImageRaw)
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
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)