diff --git a/launch/default_camera.yaml b/launch/default_camera.yaml
new file mode 100644
index 0000000..5c496f7
--- /dev/null
+++ b/launch/default_camera.yaml
@@ -0,0 +1,19 @@
+camera_model: double_sphere
+
+camera_parameters:
+ fx: 294.912
+ fy: 294.912
+ cx: 512
+ cy: 512
+ chi: 0.3
+ alpha: 0.6666667
+
+stereo_camera_parameters:
+ fx: 294.912
+ fy: 294.912
+ cx: 512
+ cy: 512
+ chi: 0.3
+ alpha: 0.6666667
+ tf_t: [2.0, 0.0, 0.0]
+ tf_r: [0.0, 0.0, 0.0, 1.0]
diff --git a/launch/default_camera_60.yaml b/launch/default_camera_60.yaml
new file mode 100644
index 0000000..768aff0
--- /dev/null
+++ b/launch/default_camera_60.yaml
@@ -0,0 +1,15 @@
+camera_model: perspective
+
+camera_parameters:
+ fx: 1024
+ fy: 1024
+ cx: 512
+ cy: 512
+
+stereo_camera_parameters:
+ fx: 1024
+ fy: 1024
+ cx: 512
+ cy: 512
+ tf_t: [2.0, 0.0, 0.0]
+ tf_r: [0.0, 0.0, 0.0, 1.0]
diff --git a/launch/kitti_camera.yaml b/launch/kitti_camera.yaml
new file mode 100644
index 0000000..282ef09
--- /dev/null
+++ b/launch/kitti_camera.yaml
@@ -0,0 +1,15 @@
+camera_model: perspective
+
+camera_parameters:
+ fx: 721.5377
+ fy: 721.5377
+ cx: 609.5593
+ cy: 172.854
+
+stereo_camera_parameters:
+ fx: 721.5377
+ fy: 721.5377
+ cx: 609.5593
+ cy: 172.854
+ tf_t: [0.533, 0.005, -0.001]
+ tf_r: [0, 0, 0, 1.0]
diff --git a/launch/matching_eval.launch b/launch/matching_eval.launch
index 0678b54..f830eed 100644
--- a/launch/matching_eval.launch
+++ b/launch/matching_eval.launch
@@ -2,8 +2,7 @@
-
-
+
@@ -17,9 +16,8 @@
+
- camera_model: '$(arg camera_model)'
- camera_parameters: $(arg camera_params)
detector_type: '$(arg detector_type)'
detector_parameters: $(arg detector_params)
descriptor_type: '$(arg descriptor_type)'
diff --git a/launch/odometry_eval.launch b/launch/odometry_eval.launch
index c6ee1c0..b47f918 100644
--- a/launch/odometry_eval.launch
+++ b/launch/odometry_eval.launch
@@ -1,8 +1,7 @@
-
-
+
@@ -19,9 +18,8 @@
+
- camera_model: '$(arg camera_model)'
- camera_parameters: $(arg camera_params)
detector_type: 'GFTT'
detector_parameters: {maxCorners: 2000, qualityLevel: 0.001, minDistance: 5, blockSize: 5}
keyframe_interval: 1
diff --git a/launch/reconstruction_eval.launch b/launch/reconstruction_eval.launch
index c3922fb..89dcb63 100644
--- a/launch/reconstruction_eval.launch
+++ b/launch/reconstruction_eval.launch
@@ -1,8 +1,7 @@
-
-
+
@@ -14,9 +13,8 @@
+
- camera_model: '$(arg camera_model)'
- camera_parameters: $(arg camera_params)
detector_type: 'GFTT'
detector_parameters: {maxCorners: 5000, qualityLevel: 0.001, minDistance: 5, blockSize: 5}
keyframe_interval: 1
diff --git a/launch/slam_eval.launch b/launch/slam_eval.launch
index c9842e7..5f92a9d 100644
--- a/launch/slam_eval.launch
+++ b/launch/slam_eval.launch
@@ -1,9 +1,7 @@
-
-
-
+
@@ -23,10 +21,8 @@
+
- camera_model: '$(arg camera_model)'
- camera_parameters: $(arg camera_params)
- stereo_camera_parameters: $(arg stereo_camera_params)
detector_type: 'GFTT'
detector_parameters: {maxCorners: 5000, qualityLevel: 0.001, minDistance: 5, blockSize: 5}
keyframe_interval: 1
@@ -54,8 +50,6 @@
stereo_matcher_num_scales: 5
stereo_matcher_error_threshold: 20
stereo_matcher_epipolar_threshold: 0.008
- stereo_tf_t: [2.0, 0.0, 0.0]
- stereo_tf_r: [0.0, 0.0, 0.0, 1.0]
diff --git a/launch/slam_eval_kitti.launch b/launch/slam_eval_kitti.launch
index fbafbea..3b3422d 100644
--- a/launch/slam_eval_kitti.launch
+++ b/launch/slam_eval_kitti.launch
@@ -1,9 +1,7 @@
-
-
-
+
@@ -23,10 +21,8 @@
+
- camera_model: '$(arg camera_model)'
- camera_parameters: $(arg camera_params)
- stereo_camera_parameters: $(arg stereo_camera_params)
detector_type: 'GFTT'
detector_parameters: {maxCorners: 5000, qualityLevel: 0.001, minDistance: 5, blockSize: 5}
keyframe_interval: 1
@@ -54,8 +50,6 @@
stereo_matcher_num_scales: 5
stereo_matcher_error_threshold: 20
stereo_matcher_epipolar_threshold: 0.008
- stereo_tf_t: [0.533, 0.005, -0.001]
- stereo_tf_r: [0, 0, 0, 1.0]
diff --git a/launch/slam_eval_t265.launch b/launch/slam_eval_t265.launch
index cf1c761..34c9ab2 100644
--- a/launch/slam_eval_t265.launch
+++ b/launch/slam_eval_t265.launch
@@ -1,9 +1,7 @@
-
-
-
+
@@ -23,10 +21,8 @@
+
- camera_model: '$(arg camera_model)'
- camera_parameters: $(arg camera_params)
- stereo_camera_parameters: $(arg stereo_camera_params)
detector_type: 'GFTT'
detector_parameters: {maxCorners: 5000, qualityLevel: 0.001, minDistance: 5, blockSize: 5}
keyframe_interval: 1
@@ -54,8 +50,6 @@
stereo_matcher_num_scales: 5
stereo_matcher_error_threshold: 20
stereo_matcher_epipolar_threshold: 0.008
- stereo_tf_t: [0.06410918, 0.0, 0.0]
- stereo_tf_r: [0.0, 0.0, 0.0, 1.0]
diff --git a/launch/slam_eval_tum.launch b/launch/slam_eval_tum.launch
index 83cdb9c..25b3e8a 100644
--- a/launch/slam_eval_tum.launch
+++ b/launch/slam_eval_tum.launch
@@ -1,9 +1,7 @@
-
-
-
+
@@ -23,10 +21,8 @@
+
- camera_model: '$(arg camera_model)'
- camera_parameters: $(arg camera_params)
- stereo_camera_parameters: $(arg stereo_camera_params)
detector_type: 'ORB'
detector_parameters: {nfeatures: 1000}
descriptor_type: 'ORB'
@@ -55,8 +51,6 @@
stereo_matcher_num_scales: 5
stereo_matcher_error_threshold: 20
stereo_matcher_epipolar_threshold: 0.008
- stereo_tf_t: [0.1010976, 0.001878, 0.00117]
- stereo_tf_r: [-0.0237542, 0.0002876, -0.0004555, 0.9997177]
diff --git a/launch/t265_camera.yaml b/launch/t265_camera.yaml
new file mode 100644
index 0000000..b397df1
--- /dev/null
+++ b/launch/t265_camera.yaml
@@ -0,0 +1,19 @@
+camera_model: double_sphere
+
+camera_parameters:
+ fx: 287.405
+ fy: 287.092
+ cx: 418.432
+ cy: 399.257
+ chi: -0.0000588
+ alpha: 0.675621
+
+stereo_camera_parameters:
+ fx: 287.405
+ fy: 287.092
+ cx: 418.432
+ cy: 399.257
+ chi: -0.0000588
+ alpha: 0.675621
+ tf_t: [0.06410918, 0.0, 0.0]
+ tf_r: [0.0, 0.0, 0.0, 1.0]
diff --git a/launch/tracking_eval.launch b/launch/tracking_eval.launch
index 1dd1fdb..2a3f5e5 100644
--- a/launch/tracking_eval.launch
+++ b/launch/tracking_eval.launch
@@ -1,8 +1,7 @@
-
-
+
@@ -12,9 +11,8 @@
+
- camera_model: '$(arg camera_model)'
- camera_parameters: $(arg camera_params)
detector_type: 'GFTT'
detector_parameters: {maxCorners: 100, qualityLevel: 0.01, minDistance: 5, blockSize: 5}
tracker_type: 'lk'
diff --git a/launch/tum_camera.yaml b/launch/tum_camera.yaml
new file mode 100644
index 0000000..dd07b83
--- /dev/null
+++ b/launch/tum_camera.yaml
@@ -0,0 +1,19 @@
+camera_model: double_sphere
+
+camera_parameters:
+ fx: 313.533725
+ fy: 313.51138991
+ cx: 510.37735
+ cy: 514.419593
+ chi: -0.18065
+ alpha: 0.59186286
+
+stereo_camera_parameters:
+ fx: 313.4386621
+ fy: 313.359903
+ cx: 505.72413717
+ cy: 510.5791992
+ chi: -0.17829397
+ alpha: 0.591774861
+ tf_t: [0.1010976, 0.001878, 0.00117]
+ tf_r: [-0.0237542, 0.0002876, -0.0004555, 0.9997177]
diff --git a/src/odometry/five_point.cc b/src/odometry/five_point.cc
index ae5d127..429e3ea 100644
--- a/src/odometry/five_point.cc
+++ b/src/odometry/five_point.cc
@@ -6,6 +6,7 @@
#include
#include
#include "optimization/reprojection_error.h"
+#include "optimization/scale_parameterization.h"
#include "camera/double_sphere.h"
#include "camera/perspective.h"
@@ -14,11 +15,12 @@ namespace omni_slam
namespace odometry
{
-FivePoint::FivePoint(int ransac_iterations, double epipolar_threshold, int trans_ransac_iterations, double reprojection_threshold, int num_ceres_threads)
+FivePoint::FivePoint(int ransac_iterations, double epipolar_threshold, int trans_ransac_iterations, double reprojection_threshold, bool fix_translation_vector, int num_ceres_threads)
: ransacIterations_(ransac_iterations),
epipolarThreshold_(epipolar_threshold),
transIterations_(trans_ransac_iterations),
reprojectionThreshold_(reprojection_threshold),
+ fixTransVec_(fix_translation_vector),
numCeresThreads_(num_ceres_threads)
{
}
@@ -74,25 +76,25 @@ int FivePoint::Compute(const std::vector &landmarks, data::Frame
bestIds = ids;
}
}
+ Vector3d tvec = bestPose.block<3, 1>(0, 3);
+ Vector3d t = bestPose.block<3, 1>(0, 3);
Matrix estPose;
- Vector3d t;
if (prev_frame.HasEstimatedPose())
{
estPose = util::TFUtil::CombineTransforms(bestPose, prev_frame.GetEstimatedInversePose());
- t = prev_frame.GetEstimatedInversePose().block<3, 1>(0, 3);
+ t = estPose.block<3, 1>(0, 3);
}
else if (prev_frame.HasPose())
{
estPose = util::TFUtil::CombineTransforms(bestPose, prev_frame.GetInversePose());
- t = prev_frame.GetInversePose().block<3, 1>(0, 3);
+ t = estPose.block<3, 1>(0, 3);
}
else
{
estPose = bestPose;
- t << 0, 0, 0;
}
std::vector transInliers;
- inliers = ComputeTranslation(bestXs, bestFeats, util::TFUtil::GetRotationFromPoseMatrix(estPose), t, transInliers);
+ inliers = ComputeTranslation(bestXs, bestFeats, util::TFUtil::GetRotationFromPoseMatrix(estPose), t, tvec, transInliers);
std::vector transInlierIds;
transInlierIds.reserve(inliers);
for (int i : transInliers)
@@ -303,9 +305,9 @@ void FivePoint::EssentialToPoses(const Matrix3d &E, std::vector &rs, s
ts.emplace_back(-UWtVt.transpose() * U.col(2));
}
-int FivePoint::ComputeTranslation(const std::vector &xs, const std::vector> &ys, const Matrix3d &R, Vector3d &t, std::vector &inlier_indices) const
+int FivePoint::ComputeTranslation(const std::vector &xs, const std::vector> &ys, const Matrix3d &R, Vector3d &t, const Vector3d &tvec, std::vector &inlier_indices) const
{
- int inliers = TranslationRANSAC(xs, ys, R, t);
+ int inliers = TranslationRANSAC(xs, ys, R, t, tvec);
inlier_indices = GetTranslationInlierIndices(xs, ys, R, t);
std::vector xs_inliers;
std::vector> ys_inliers;
@@ -316,11 +318,11 @@ int FivePoint::ComputeTranslation(const std::vector &xs, const std::ve
xs_inliers.push_back(xs[inx]);
ys_inliers.push_back(ys[inx]);
}
- OptimizeTranslation(xs_inliers, ys_inliers, R, t);
+ OptimizeTranslation(xs_inliers, ys_inliers, R, t, tvec);
return inliers;
}
-int FivePoint::TranslationRANSAC(const std::vector &xs, const std::vector> &ys, const Matrix3d &R, Vector3d &t) const
+int FivePoint::TranslationRANSAC(const std::vector &xs, const std::vector> &ys, const Matrix3d &R, Vector3d &t, const Vector3d &tvec) const
{
int bestInliers = 0;
std::random_device rd;
@@ -340,7 +342,7 @@ int FivePoint::TranslationRANSAC(const std::vector &xs, const std::vec
std::vector x{xs[indices[i]]};
std::vector> y{ys[indices[i]]};
Vector3d tmpT = t;
- if (OptimizeTranslation(x, y, R, tmpT))
+ if (OptimizeTranslation(x, y, R, tmpT, tvec))
{
int inliers = GetTranslationInlierIndices(xs, ys, R, tmpT).size();
#pragma omp critical
@@ -356,7 +358,7 @@ int FivePoint::TranslationRANSAC(const std::vector &xs, const std::vec
return bestInliers;
}
-bool FivePoint::OptimizeTranslation(const std::vector &xs, const std::vector> &ys, const Matrix3d &R, Vector3d &t) const
+bool FivePoint::OptimizeTranslation(const std::vector &xs, const std::vector> &ys, const Matrix3d &R, Vector3d &t, const Vector3d &tvec) const
{
ceres::Problem problem;
ceres::LossFunction *loss_function = nullptr;
@@ -385,9 +387,13 @@ bool FivePoint::OptimizeTranslation(const std::vector &xs, const std::
{
problem.AddResidualBlock(cost_function, loss_function, &quatData[0], &tData[0], &landmarks[landmarks.size() - 3]);
problem.SetParameterBlockConstant(&landmarks[landmarks.size() - 3]);
- problem.SetParameterBlockConstant(&quatData[0]);
}
}
+ problem.SetParameterBlockConstant(&quatData[0]);
+ if (fixTransVec_)
+ {
+ problem.SetParameterization(&tData[0], optimization::ScaleParameterization<3>::Create(tvec));
+ }
ceres::Solver::Options options;
options.max_num_iterations = 100;
options.linear_solver_type = ceres::DENSE_SCHUR;
diff --git a/src/odometry/five_point.h b/src/odometry/five_point.h
index 7f5e98e..45d2798 100644
--- a/src/odometry/five_point.h
+++ b/src/odometry/five_point.h
@@ -15,7 +15,7 @@ namespace odometry
class FivePoint : public PoseEstimator
{
public:
- FivePoint(int ransac_iterations, double epipolar_threshold, int trans_ransac_iterations, double reprojection_threshold, int num_ceres_threads = 1);
+ FivePoint(int ransac_iterations, double epipolar_threshold, int trans_ransac_iterations, double reprojection_threshold, bool fix_translation_vector, int num_ceres_threads = 1);
int Compute(const std::vector &landmarks, data::Frame &cur_frame, const data::Frame &prev_frame, std::vector &inlier_indices) const;
int ComputeE(const std::vector &landmarks, const data::Frame &frame1, const data::Frame &frame2, Matrix3d &E, std::vector &inlier_indices, bool stereo = false) const;
@@ -25,9 +25,9 @@ class FivePoint : public PoseEstimator
void FivePointRelativePose(const std::vector &x1, const std::vector &x2, std::vector &Es) const;
std::vector GetEInlierIndices(const std::vector &x1, const std::vector &x2, const Matrix3d &E) const;
void EssentialToPoses(const Matrix3d &E, std::vector &rs, std::vector &ts) const;
- int ComputeTranslation(const std::vector &xs, const std::vector> &ys, const Matrix3d &R, Vector3d &t, std::vector &inlier_indices) const;
- int TranslationRANSAC(const std::vector &xs, const std::vector> &ys, const Matrix3d &R, Vector3d &t) const;
- bool OptimizeTranslation(const std::vector &xs, const std::vector> &ys, const Matrix3d &R, Vector3d &t) const;
+ int ComputeTranslation(const std::vector &xs, const std::vector> &ys, const Matrix3d &R, Vector3d &t, const Vector3d &tvec, std::vector &inlier_indices) const;
+ int TranslationRANSAC(const std::vector &xs, const std::vector> &ys, const Matrix3d &R, Vector3d &t, const Vector3d &tvec) const;
+ bool OptimizeTranslation(const std::vector &xs, const std::vector> &ys, const Matrix3d &R, Vector3d &t, const Vector3d &tvec) const;
std::vector GetTranslationInlierIndices(const std::vector &xs, const std::vector> &ys, const Matrix3d &R, const Vector3d &t) const;
Vector3d TriangulateDLT(const Vector3d &x1, const Vector3d &x2, const Matrix &pose1, const Matrix &pose2) const;
@@ -35,6 +35,7 @@ class FivePoint : public PoseEstimator
int transIterations_;
double epipolarThreshold_;
double reprojectionThreshold_;
+ bool fixTransVec_;
int numCeresThreads_;
};
diff --git a/src/optimization/scale_parameterization.h b/src/optimization/scale_parameterization.h
new file mode 100644
index 0000000..e88aa58
--- /dev/null
+++ b/src/optimization/scale_parameterization.h
@@ -0,0 +1,46 @@
+#ifndef _SCALE_PARAMETERIZATION_H_
+#define _SCALE_PARAMETERIZATION_H_
+
+#include
+#include
+
+using namespace Eigen;
+
+namespace omni_slam
+{
+namespace optimization
+{
+
+template
+class ScaleParameterization
+{
+public:
+ ScaleParameterization(const Matrix &vec)
+ : vec_(vec.normalized())
+ {
+ }
+
+ template
+ bool operator()(const T *x, const T *delta, T *x_plus_delta) const
+ {
+ Matrix vec = vec_.template cast();
+ for (int i = 0; i < G; i++)
+ {
+ x_plus_delta[i] = x[i] + delta[0] * vec[i];
+ }
+ return true;
+ }
+
+ static ceres::LocalParameterization* Create(const Matrix &vec)
+ {
+ return new ceres::AutoDiffLocalParameterization(new ScaleParameterization(vec));
+ }
+
+private:
+ const Matrix vec_;
+};
+
+}
+}
+
+#endif /* _SCALE_PARAMETERIZATION_H_ */
diff --git a/src/ros/eval_base.cc b/src/ros/eval_base.cc
index 3ca4180..51d13e4 100644
--- a/src/ros/eval_base.cc
+++ b/src/ros/eval_base.cc
@@ -59,8 +59,8 @@ EvalBase::EvalBase(const ::ros::NodeHandle &nh, const ::ros::NodeHandle &n
stereoT.reserve(3);
std::vector stereoR;
stereoR.reserve(4);
- nhp_.getParam("stereo_tf_t", stereoT);
- nhp_.getParam("stereo_tf_r", stereoR);
+ nhp_.getParam("stereo_camera_parameters/tf_t", stereoT);
+ nhp_.getParam("stereo_camera_parameters/tf_r", stereoR);
Quaterniond q(stereoR[3], stereoR[0], stereoR[1], stereoR[2]);
Vector3d t(stereoT[0], stereoT[1], stereoT[2]);
stereoPose_ = util::TFUtil::QuaternionTranslationToPoseMatrix(q, t);
diff --git a/src/ros/odometry_eval.cc b/src/ros/odometry_eval.cc
index 112e11f..dd6f7c0 100644
--- a/src/ros/odometry_eval.cc
+++ b/src/ros/odometry_eval.cc
@@ -51,7 +51,11 @@ OdometryEval::OdometryEval(const ::ros::NodeHandle &nh, const ::ros::Nod
}
else if (odometryType == "five_point")
{
- poseEstimator.reset(new odometry::FivePoint(fivePointRansacIterations, fivePointThreshold, iterations, reprojThresh, numCeresThreads));
+ poseEstimator.reset(new odometry::FivePoint(fivePointRansacIterations, fivePointThreshold, iterations, reprojThresh, false, numCeresThreads));
+ }
+ else if (odometryType == "five_point_fixed_translation")
+ {
+ poseEstimator.reset(new odometry::FivePoint(fivePointRansacIterations, fivePointThreshold, iterations, reprojThresh, true, numCeresThreads));
}
else
{
diff --git a/src/ros/tracking_eval.cc b/src/ros/tracking_eval.cc
index b727271..e144d29 100644
--- a/src/ros/tracking_eval.cc
+++ b/src/ros/tracking_eval.cc
@@ -77,7 +77,7 @@ TrackingEval::TrackingEval(const ::ros::NodeHandle &nh, const ::ros::Nod
ROS_ERROR("Invalid tracker type specified");
}
- unique_ptr checker(new odometry::FivePoint(fivePointRansacIterations, fivePointThreshold, 0, 0));
+ unique_ptr checker(new odometry::FivePoint(fivePointRansacIterations, fivePointThreshold, 0, false, 0));
trackingModule_.reset(new module::TrackingModule(detector, tracker, checker, minFeaturesRegion, maxFeaturesRegion));
}