19 #ifndef LOCALIZATION_VIVE_LOCALIZATION_SRC_VIVE_H_
20 #define LOCALIZATION_VIVE_LOCALIZATION_SRC_VIVE_H_
28 #include <geometry_msgs/TransformStamped.h>
29 #include <ff_hw_msgs/ViveLighthouses.h>
30 #include <ff_hw_msgs/ViveTrackers.h>
31 #include <ff_hw_msgs/ViveLight.h>
32 #include <ff_msgs/CameraRegistration.h>
33 #include <ff_msgs/VisualLandmarks.h>
36 #include <opencv2/calib3d/calib3d.hpp>
40 #include <Eigen/Geometry>
119 std::string
const& frame_world,
120 std::string
const& frame_vive,
121 std::string
const& frame_body,
122 double registration[6],
129 Eigen::Quaterniond
toQuaternion(
double roll,
double pitch,
double yaw);
136 Eigen::Quaterniond & modification_quaternion);
140 std::map<std::string, Eigen::Affine3d> & lighthouses);
144 std::map<std::string, Tracker> & trackers);
158 bool SolvePnP(std::vector<cv::Point3f>
const& obj,
159 std::vector<cv::Point2f>
const& img,
168 template <
typename T>
170 Eigen::Matrix<T, 3, Eigen::Dynamic> in,
171 Eigen::Matrix<T, 3, Eigen::Dynamic> out,
172 Eigen::Transform<T, 3, Eigen::Affine> &A,
bool allowScale) {
174 A.linear() = Eigen::Matrix<T, 3, 3>::Identity(3, 3);
175 A.translation() = Eigen::Matrix<T, 3, 1>::Zero();
182 if (in.cols() != out.cols()) {
188 T dist_in = T(0.0), dist_out = T(0.0);
189 for (
int col = 0; col < in.cols()-1; col++) {
190 dist_in += (in.col(col+1) - in.col(col)).norm();
191 dist_out += (out.col(col+1) - out.col(col)).norm();
193 if (dist_in <= T(0.0) || dist_out <= T(0.0))
197 scale = dist_out/dist_in;
201 Eigen::Matrix<T, 3, 1> in_ctr = Eigen::Matrix<T, 3, 1>::Zero();
202 Eigen::Matrix<T, 3, 1> out_ctr = Eigen::Matrix<T, 3, 1>::Zero();
203 for (
int col = 0; col < in.cols(); col++) {
204 in_ctr += in.col(col);
205 out_ctr += out.col(col);
207 in_ctr /= T(in.cols());
208 out_ctr /= T(out.cols());
209 for (
int col = 0; col < in.cols(); col++) {
210 in.col(col) -= in_ctr;
211 out.col(col) -= out_ctr;
214 Eigen::Matrix<T, Eigen::Dynamic, Eigen::Dynamic> Cov = in * out.transpose();
215 Eigen::JacobiSVD < Eigen::Matrix < T, Eigen::Dynamic, Eigen::Dynamic > > svd(Cov,
216 Eigen::ComputeThinU | Eigen::ComputeThinV);
218 T d = (svd.matrixV() * svd.matrixU().transpose()).determinant();
223 Eigen::Matrix<T, 3, 3> I = Eigen::Matrix<T, 3, 3>::Identity(3, 3);
225 Eigen::Matrix<T, 3, 3> R = svd.matrixV() * I * svd.matrixU().transpose();
227 A.linear() = scale * R;
228 A.translation() = scale*(out_ctr - R*in_ctr);
234 template <
typename T>
235 static void Predict(T
const* params, T
const* xyz, T* ang,
bool correct) {
236 for (
size_t i = 0; i < 2; i++) {
246 ang[i] = atan2(a, b);
252 ang[i] -= asin((c * tan(p[
PARAM_TILT])) / sqrt(a*a + b*b));
255 ang[i] -= p[
PARAM_CURVE] * atan2(c, a) * atan2(c, a);
261 template <
typename T>
262 static void Correct(T
const* params, T * angle,
bool correct) {
264 T ideal[2], pred[2], xyz[3];
267 for (
size_t i = 0; i < 10; i++) {
268 xyz[0] = T(-1.0) / tan(ideal[0]);
269 xyz[1] = T(-1.0) / tan(ideal[1]);
271 Predict(params, xyz, pred, correct);
272 ideal[0] += (angle[0] - pred[0]);
273 ideal[1] += (angle[1] - pred[1]);
282 #endif // LOCALIZATION_VIVE_LOCALIZATION_SRC_VIVE_H_