summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorStanislaw Halik <sthalik@misaki.pl>2014-11-02 06:04:05 +0100
committerStanislaw Halik <sthalik@misaki.pl>2014-11-02 06:04:05 +0100
commitc044ce0d0830902b9ca86dcd9a725e5ef4f72eb1 (patch)
tree30283eea8cbc4d73ee85440f1e1858ea276e5245
parent69dc9c96a1f544857d3909dd0412515840d544ca (diff)
use quaternions for centering
@KyokushinPL says was the only version that worked. Let's give it a try. Goddamn issue: #63
-rw-r--r--ftnoir_posewidget/glwidget.cpp23
-rw-r--r--opentrack/quat.hpp71
-rw-r--r--opentrack/tracker.cpp32
-rw-r--r--opentrack/tracker.h3
4 files changed, 93 insertions, 36 deletions
diff --git a/ftnoir_posewidget/glwidget.cpp b/ftnoir_posewidget/glwidget.cpp
index bfb9190d..07445c8a 100644
--- a/ftnoir_posewidget/glwidget.cpp
+++ b/ftnoir_posewidget/glwidget.cpp
@@ -34,26 +34,17 @@ void GLWidget::paintEvent ( QPaintEvent * event ) {
void GLWidget::rotateBy(double xAngle, double yAngle, double zAngle)
{
- double c1 = cos(zAngle / 57.295781);
- double s1 = sin(zAngle / 57.295781);
+ double c1 = cos(yAngle / 57.295781);
+ double s1 = sin(yAngle / 57.295781);
double c2 = cos(xAngle / 57.295781);
double s2 = sin(xAngle / 57.295781);
- double c3 = cos(yAngle / 57.295781);
- double s3 = sin(yAngle / 57.295781);
+ double c3 = cos(zAngle / 57.295781);
+ double s3 = sin(zAngle / 57.295781);
double foo[] = {
- // z
- c1 * c2,
- c1 * s2 * s3 - c3 * s1,
- s1 * s3 + c1 * c3 * s2,
- // y
- c2 * s1,
- c1 * c3 + s1 * s2 * s3,
- c3 * s1 * s2 - c1 * s3,
- // x
- -s2,
- c2 * s3,
- c2 * c3
+ c2*c3, -c2*s3, s2,
+ c1*s3+c3*s1*s2, c1*c3-s1*s2*s3, -c2*s1,
+ s1*s3-c1*c3*s2, c3*s1+c1*s2*s3, c1*c2,
};
for (int i = 0; i < 9; i++)
diff --git a/opentrack/quat.hpp b/opentrack/quat.hpp
new file mode 100644
index 00000000..e5e74df4
--- /dev/null
+++ b/opentrack/quat.hpp
@@ -0,0 +1,71 @@
+/* Copyright (c) 2012 Patrick Ruoff
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ */
+
+#pragma once
+#include <cmath>
+
+class Quat {
+private:
+ static constexpr double pi = 3.141592653;
+ static constexpr double r2d = 180./pi;
+ double a,b,c,d; // quaternion coefficients
+public:
+ Quat() : a(1.),b(0.),c(0.),d(0.) {}
+ Quat(double yaw, double pitch, double roll) { *this = from_euler_rads(yaw, pitch, roll); }
+ Quat(double a, double b, double c, double d) : a(a),b(b),c(c),d(d) {}
+
+ Quat inv() const
+ {
+ return Quat(a,-b,-c, -d);
+ }
+
+ // conversions
+ // see http://en.wikipedia.org/wiki/Conversion_between_quaternions_and_Euler_angles
+ static Quat from_euler_rads(double yaw, double pitch, double roll)
+ {
+
+ const double sin_phi = sin(roll/2.);
+ const double cos_phi = cos(roll/2.);
+ const double sin_the = sin(pitch/2.);
+ const double cos_the = cos(pitch/2.);
+ const double sin_psi = sin(yaw/2.);
+ const double cos_psi = cos(yaw/2.);
+
+ Quat q;
+
+ q.a = cos_phi*cos_the*cos_psi + sin_phi*sin_the*sin_psi;
+ q.b = sin_phi*cos_the*cos_psi - cos_phi*sin_the*sin_psi;
+ q.c = cos_phi*sin_the*cos_psi + sin_phi*cos_the*sin_psi;
+ q.d = cos_phi*cos_the*sin_psi - sin_phi*sin_the*cos_psi;
+
+ return q;
+ }
+
+ void to_euler_rads(double& yaw, double& pitch, double& roll) const
+ {
+ roll = atan2(2.*(a*b + c*d), 1. - 2.*(b*b + c*c));
+ pitch = asin(2.*(a*c - b*d));
+ yaw = atan2(2.*(a*d + b*c), 1. - 2.*(c*c + d*d));
+ }
+
+ void to_euler_degrees(double& yaw, double& pitch, double& roll) const
+ {
+ to_euler_rads(yaw, pitch, roll);
+ yaw *= r2d;
+ pitch *= r2d;
+ roll *= r2d;
+ }
+
+ const Quat operator*(const Quat& B) const
+ {
+ const Quat& A = *this;
+ return Quat(A.a*B.a - A.b*B.b - A.c*B.c - A.d*B.d, // quaternion multiplication
+ A.a*B.b + A.b*B.a + A.c*B.d - A.d*B.c,
+ A.a*B.c - A.b*B.d + A.c*B.a + A.d*B.b,
+ A.a*B.d + A.b*B.c - A.c*B.b + A.d*B.a);
+ }
+};
diff --git a/opentrack/tracker.cpp b/opentrack/tracker.cpp
index 4a9be069..b9b43ee5 100644
--- a/opentrack/tracker.cpp
+++ b/opentrack/tracker.cpp
@@ -28,7 +28,6 @@ Tracker::Tracker(main_settings& s, Mappings &m, SelectedLibraries &libs) :
enabledp(true),
should_quit(false),
libs(libs),
- r_b (dmat<3, 3>::eye()),
t_b {0,0,0}
{
}
@@ -48,17 +47,6 @@ double Tracker::map(double pos, bool invertp, Mapping& axis)
return fc.getValue(pos) + axis.opts.zero;
}
-// http://stackoverflow.com/a/18436193
-static dmat<3, 1> rmat_to_euler(const dmat<3, 3>& R)
-{
- const double tmp[] = {
- -atan2( -R(2,0), sqrt(R(2,1)*R(2,1) + R(2,2)*R(2,2)) ),
- -atan2( R(2,1), R(2,2)),
- -atan2( R(1,0), R(0,0)),
- };
- return dmat<3, 1>(tmp);
-}
-
// tait-bryan angles, not euler
static dmat<3, 3> euler_to_rmat(const double* input)
{
@@ -124,26 +112,32 @@ void Tracker::logic()
for (int i = 0; i < 6; i++)
filtered_pose[i] *= inverts[i] ? -1. : 1.;
+ static constexpr double pi = 3.141592653;
+ static constexpr double d2r = pi / 180.;
+
if (centerp)
{
centerp = false;
- dmat<3, 1> tmp;
- r_b = euler_to_rmat(&filtered_pose[Yaw]);
for (int i = 0; i < 3; i++)
t_b[i] = filtered_pose(i);
+ q_b = Quat::from_euler_rads(filtered_pose(Yaw) * d2r,
+ filtered_pose(Pitch) * d2r,
+ filtered_pose(Roll) * d2r);
}
Pose raw_centered;
{
- const dmat<3, 3> rmat = euler_to_rmat(&filtered_pose[Yaw]);
- const dmat<3, 3> m_ = rmat * r_b.t();
- const auto euler = rmat_to_euler(m_);
+ const Quat q(filtered_pose(Yaw)*d2r,
+ filtered_pose(Pitch)*d2r,
+ filtered_pose(Roll)*d2r);
+ const Quat q_ = q * q_b.inv();
+ double ypr[3];
+ q_.to_euler_degrees(ypr[0], ypr[1], ypr[2]);
for (int i = 0; i < 3; i++)
{
- static constexpr double pi = 3.141592653;
raw_centered(i) = filtered_pose(i) - t_b[i];
- raw_centered(i+3) = euler(i, 0) * 180./pi;
+ raw_centered(i+3) = ypr[i];
}
}
diff --git a/opentrack/tracker.h b/opentrack/tracker.h
index 23939576..feb1f903 100644
--- a/opentrack/tracker.h
+++ b/opentrack/tracker.h
@@ -7,6 +7,7 @@
#include "plugin-support.h"
#include "mappings.hpp"
#include "pose.hpp"
+#include "quat.hpp"
#include "simple-mat.hpp"
#include "../qfunctionconfigurator/functionconfig.h"
@@ -32,7 +33,7 @@ private:
std::atomic<bool> should_quit;
SelectedLibraries const& libs;
- dmat<3, 3> r_b;
+ Quat q_b;
double t_b[3];
double map(double pos, bool invertp, Mapping& axis);