33 unsigned int ResectionSolver::solve(
const Eigen::Vector2d& base_A,
const Eigen::Vector2d& base_B,
const Eigen::Vector2d& base_C)
38 solve_for_lengths((base_A-base_B).norm(), (base_B-base_C).norm(), (base_C-base_A).norm());
41 for (
int i = (
int)
solutions_a.size()-1; i >= 0; i--)
62 Eigen::Vector3d
ResectionSolver::solve_for_top(
const Eigen::Vector2d& base_A,
const Eigen::Vector2d& base_B,
const Eigen::Vector2d& base_C,
double length_AS,
double length_BS,
double length_CS)
64 Eigen::Vector2d base_B_new, base_C_new;
65 base_B_new = base_B - base_A;
66 base_C_new = base_C - base_A;
68 alpha = (pow(base_B_new[0],2.0) + pow(base_B_new[1],2.0) + pow(length_AS,2.0) - pow(length_BS,2.0)) / 2.0;
70 beta = (pow(base_C_new[0],2.0) + pow(base_C_new[1],2.0) + pow(length_AS,2.0) - pow(length_CS,2.0)) / 2.0;
72 Y = (alpha*base_C_new[0]-beta*base_B_new[0])/(base_B_new[1]*base_C_new[0]-base_C_new[1]*base_B_new[0]);
73 if (base_B_new[0] != 0.0)
75 X = (alpha - Y*base_B_new[1])/base_B_new[0];
79 X = (beta - Y*base_C_new[1])/base_C_new[0];
82 Z = sqrt(pow(length_CS, 2.0) - pow(X - base_C_new[0], 2.0) - pow(Y - base_C_new[1], 2.0));
83 return Eigen::Vector3d(X + base_A[0], Y + base_A[1], Z);
97 double inv_d22 = 1. / (side_C * side_C);
98 double a = inv_d22 * (side_A * side_A);
99 double b = inv_d22 * (side_B * side_B);
101 double a2 = a * a, b2 = b * b, p2 = p * p, q2 = q * q, r2 = r * r;
102 double pr = p * r, pqr = q * pr;
105 if (p2 + q2 + r2 - pqr - 1 == 0)
108 double ab = a * b, a_2 = 2*a;
110 double A = -2 * b + b2 + a2 + 1 + ab*(2 - r2) - a_2;
113 if (A == 0)
return 0;
117 double B = q*(-2*(ab + a2 + 1 - b) + r2*ab + a_4) + pr*(b - b2 + ab);
118 double C = q2 + b2*(r2 + p2 - 2) - b*(p2 + pqr) - ab*(r2 + pqr) + (a2 - a_2)*(2 + q2) + 2;
119 double D = pr*(ab-b2+b) + q*((p2-2)*b + 2 * (ab - a2) + a_4 - 2);
120 double E = 1 + 2*(b - a - ab) + b2 - b*p2 + a2;
122 double temp = (p2*(a-1+b) + r2*(a-1-b) + pqr - a*pqr);
123 double b0 = b * temp * temp;
128 double real_roots[4];
129 int n =
SolveP4(real_roots, B/A, C/A,D/A, E/A);
134 int nb_solutions = 0;
135 double r3 = r2*r, pr2 = p*r2, r3q = r3 * q;
136 double inv_b0 = 1. / b0;
139 for(
int i = 0; i < n; i++) {
140 double x = real_roots[i];
149 ((1-a-b)*x2 + (q*a-q)*x + 1 - a + b) *
150 (((r3*(a2 + ab*(2 - r2) - a_2 + b2 - 2*b + 1)) * x +
152 (r3q*(2*(b-a2) + a_4 + ab*(r2 - 2) - 2) + pr2*(1 + a2 + 2*(ab-a-b) + r2*(b - b2) + b2))) * x2 +
154 (r3*(q2*(1-2*a+a2) + r2*(b2-ab) - a_4 + 2*(a2 - b2) + 2) + r*p2*(b2 + 2*(ab - b - a) + 1 + a2) + pr2*q*(a_4 + 2*(b - ab - a2) - 2 - r2*b)) * x +
156 2*r3q*(a_2 - b - a2 + ab - 1) + pr2*(q2 - a_4 + 2*(a2 - b2) + r2*b + q2*(a2 - a_2) + 2) +
157 p2*(p*(2*(ab - a - b) + a2 + b2 + 1) + 2*q*r*(b + a_2 - a2 - ab - 1)));
163 double y = inv_b0 * b1;
164 double v = x2 + y*y - x*y*r;
169 double Z = side_C / sqrt(v);
186 Eigen::Matrix4d *transformation =
new Eigen::Matrix4d();
188 Eigen::Vector3d x_axis, y_axis, z_axis;
190 z_axis = Eigen::Vector3d(solution[0] - base_B[0], solution[1] - base_B[1], solution[2]);
196 x_axis = Eigen::Vector3d(base_A[0] - solution[0], base_A[1] - solution[1], -solution[2]);
197 y_axis = Eigen::Vector3d(base_C[0] - solution[0], base_C[1] - solution[1], -solution[2]);
203 x_axis = x_axis - x_axis.dot(z_axis)*z_axis;
205 y_axis = y_axis - y_axis.dot(z_axis)*z_axis - y_axis.dot(x_axis)*x_axis;
208 (*transformation)(0,0) = x_axis[0];
209 (*transformation)(1,0) = x_axis[1];
210 (*transformation)(2,0) = x_axis[2];
211 (*transformation)(3,0) = 0.0;
212 (*transformation)(0,1) = y_axis[0];
213 (*transformation)(1,1) = y_axis[1];
214 (*transformation)(2,1) = y_axis[2];
215 (*transformation)(3,1) = 0.0;
216 (*transformation)(0,2) = z_axis[0];
217 (*transformation)(1,2) = z_axis[1];
218 (*transformation)(2,2) = z_axis[2];
219 (*transformation)(3,2) = 0.0;
220 (*transformation)(0,3) = solution[0];
221 (*transformation)(1,3) = solution[1];
222 (*transformation)(2,3) = solution[2];
223 (*transformation)(3,3) = 1.0;
225 return *transformation;
boost::shared_ptr< Calibration_Object > calibrationObject
int SolveP4(double *x, double a, double b, double c, double d)
int solve_for_lengths(double side_A, double side_B, double side_C)
std::vector< Eigen::Vector3d, Eigen::aligned_allocator< Eigen::Vector3d > > solutions
Eigen::Matrix4d calculateTransformationMatrix(const Eigen::Vector2d &base_A, const Eigen::Vector2d &base_B, const Eigen::Vector2d &base_C, const Eigen::Vector3d &solution)
boost::shared_ptr< FeasibilityChecker > feasibilityChecker
unsigned int solve(const Eigen::Vector2d &base_A, const Eigen::Vector2d &base_B, const Eigen::Vector2d &base_C)
ResectionSolver(boost::shared_ptr< Calibration_Object > calibrationObject, boost::shared_ptr< FeasibilityChecker > feasibilityChecker)
std::vector< double > solutions_a
std::vector< double > solutions_b
#define ROS_DEBUG_STREAM(args)
#define ROS_INFO_STREAM(args)
Eigen::Vector3d solve_for_top(const Eigen::Vector2d &base_A, const Eigen::Vector2d &base_B, const Eigen::Vector2d &base_C, double length_AS, double length_BS, double length_CS)
std::vector< double > solutions_c