summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorStanislaw Halik <sthalik@misaki.pl>2018-07-09 07:18:25 +0200
committerStanislaw Halik <sthalik@misaki.pl>2018-07-09 07:18:25 +0200
commitf5610a1ac847f17402415e4bf1080f84fd8d185f (patch)
treed8dda5864941a1d903a1fcf87ece585aa24d532b
parent793cea587159a0ba01fec6af28e899697ef4da79 (diff)
tracker/tobii: add prototype support for accumulative mode
-rw-r--r--tracker-tobii-eyex/head-tracking.cpp89
-rw-r--r--tracker-tobii-eyex/lang/nl_NL.ts45
-rw-r--r--tracker-tobii-eyex/lang/ru_RU.ts45
-rw-r--r--tracker-tobii-eyex/lang/stub.ts45
-rw-r--r--tracker-tobii-eyex/lang/zh_CN.ts45
-rw-r--r--tracker-tobii-eyex/tobii-eyex-dialog.cpp5
-rw-r--r--tracker-tobii-eyex/tobii-eyex-dialog.ui449
-rw-r--r--tracker-tobii-eyex/tobii-eyex.cpp106
-rw-r--r--tracker-tobii-eyex/tobii-eyex.hpp57
-rw-r--r--tracker-tobii-eyex/tobii-settings.hpp11
10 files changed, 150 insertions, 747 deletions
diff --git a/tracker-tobii-eyex/head-tracking.cpp b/tracker-tobii-eyex/head-tracking.cpp
new file mode 100644
index 00000000..8973293d
--- /dev/null
+++ b/tracker-tobii-eyex/head-tracking.cpp
@@ -0,0 +1,89 @@
+#include "tobii-eyex.hpp"
+#include "compat/math.hpp"
+#include "compat/math-imports.hpp"
+
+real tobii_eyex_tracker::gain(real x)
+{
+ // simple sigmoid
+ x = clamp(x * 12 - 6, -6, 6);
+ x = 1 / (1 + exp(-x));
+ x = x * 2 - 1;
+ return clamp(x, -1, 1);
+}
+
+void tobii_eyex_tracker::data(double* data)
+{
+ real px, py, max_x, max_y;
+ bool fresh;
+
+ {
+ QMutexLocker l(&global_state_mtx);
+
+ if (!dev_state.is_valid())
+ return;
+
+ px = dev_state.px;
+ py = dev_state.py;
+ max_x = dev_state.display_res_x - 1;
+ max_y = dev_state.display_res_y - 1;
+
+ fresh = dev_state.fresh;
+ dev_state.fresh = false;
+ }
+
+ if (fresh)
+ {
+ real x = (2*px - max_x)/max_x; // (-1)->1
+ real y = (2*py - max_y)/max_y; // idem
+
+ data[TX] = x * 50;
+ data[TY] = y * -50;
+
+ const double dt = t.elapsed_seconds();
+ t.start();
+
+ const double max_yaw = *s.acc_max_yaw, max_pitch = *s.acc_max_pitch;
+ const double dz_ = *s.acc_dz; // closed set of 0->x, some arbitrary x < 1
+
+ for (auto* k_ : { &x, &y })
+ {
+ real& k = *k_;
+
+ if (std::fabs(k) < dz_)
+ k = 0;
+ else
+ {
+ // input has reduced dynamic range
+ k -= copysign(dz_, k);
+ k *= 1 + dz_;
+ }
+ }
+
+ const double c = *s.acc_speed;
+
+ // XXX check this for stability -sh 20180709
+ const double yaw_delta = gain(x) * c * dt;
+ const double pitch_delta = gain(y) * c * dt;
+
+ yaw += yaw_delta;
+ pitch += pitch_delta;
+
+ yaw = clamp(yaw, -max_yaw, max_yaw);
+ pitch = clamp(pitch, -max_pitch, max_pitch);
+ }
+
+ if (do_center)
+ {
+ do_center = false;
+ yaw = 0;
+ pitch = 0;
+ }
+
+ data[Yaw] = yaw;
+ data[Pitch] = pitch;
+ data[Roll] = 0;
+ data[TZ] = 0; // XXX TODO
+
+ // tan(x) in 0->.7 is almost linear. we don't need to adjust.
+ // .7 is 40 degrees which is already quite a lot from the monitor.
+}
diff --git a/tracker-tobii-eyex/lang/nl_NL.ts b/tracker-tobii-eyex/lang/nl_NL.ts
index 35c7f98a..47076f04 100644
--- a/tracker-tobii-eyex/lang/nl_NL.ts
+++ b/tracker-tobii-eyex/lang/nl_NL.ts
@@ -7,51 +7,6 @@
<source>Tracker options</source>
<translation type="unfinished"></translation>
</message>
- <message>
- <source>Tracking settings</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>Accumulative mode shifts the view toward a target that may be offscreen then fixes upon it.
-On the other hand, the snap mode allows for a quick glance outside the field of vision.</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>Accumulative mode settings</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>Screen edge length</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>Max yaw</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>Max pitch</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>Position output</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>Enabled</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>Snap mode settings</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>Tracking mode</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>Speed</source>
- <translation type="unfinished"></translation>
- </message>
</context>
<context>
<name>tobii_eyex_tracker</name>
diff --git a/tracker-tobii-eyex/lang/ru_RU.ts b/tracker-tobii-eyex/lang/ru_RU.ts
index 806c23b8..65ec8ca5 100644
--- a/tracker-tobii-eyex/lang/ru_RU.ts
+++ b/tracker-tobii-eyex/lang/ru_RU.ts
@@ -7,51 +7,6 @@
<source>Tracker options</source>
<translation type="unfinished"></translation>
</message>
- <message>
- <source>Tracking settings</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>Accumulative mode shifts the view toward a target that may be offscreen then fixes upon it.
-On the other hand, the snap mode allows for a quick glance outside the field of vision.</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>Accumulative mode settings</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>Screen edge length</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>Max yaw</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>Max pitch</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>Position output</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>Enabled</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>Snap mode settings</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>Tracking mode</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>Speed</source>
- <translation type="unfinished"></translation>
- </message>
</context>
<context>
<name>tobii_eyex_tracker</name>
diff --git a/tracker-tobii-eyex/lang/stub.ts b/tracker-tobii-eyex/lang/stub.ts
index 26acccaa..6e4c7d1a 100644
--- a/tracker-tobii-eyex/lang/stub.ts
+++ b/tracker-tobii-eyex/lang/stub.ts
@@ -7,51 +7,6 @@
<source>Tracker options</source>
<translation type="unfinished"></translation>
</message>
- <message>
- <source>Tracking settings</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>Accumulative mode shifts the view toward a target that may be offscreen then fixes upon it.
-On the other hand, the snap mode allows for a quick glance outside the field of vision.</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>Accumulative mode settings</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>Screen edge length</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>Max yaw</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>Max pitch</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>Position output</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>Enabled</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>Snap mode settings</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>Tracking mode</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>Speed</source>
- <translation type="unfinished"></translation>
- </message>
</context>
<context>
<name>tobii_eyex_tracker</name>
diff --git a/tracker-tobii-eyex/lang/zh_CN.ts b/tracker-tobii-eyex/lang/zh_CN.ts
index b7896059..6e4c7d1a 100644
--- a/tracker-tobii-eyex/lang/zh_CN.ts
+++ b/tracker-tobii-eyex/lang/zh_CN.ts
@@ -7,51 +7,6 @@
<source>Tracker options</source>
<translation type="unfinished"></translation>
</message>
- <message>
- <source>Tracking settings</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>Accumulative mode shifts the view toward a target that may be offscreen then fixes upon it.
-On the other hand, the snap mode allows for a quick glance outside the field of vision.</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>Tracking mode</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>Accumulative mode settings</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>Screen edge length</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>Speed</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>Max yaw</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>Max pitch</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>Position output</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>Enabled</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>Snap mode settings</source>
- <translation type="unfinished"></translation>
- </message>
</context>
<context>
<name>tobii_eyex_tracker</name>
diff --git a/tracker-tobii-eyex/tobii-eyex-dialog.cpp b/tracker-tobii-eyex/tobii-eyex-dialog.cpp
index 807542e1..6ab916be 100644
--- a/tracker-tobii-eyex/tobii-eyex-dialog.cpp
+++ b/tracker-tobii-eyex/tobii-eyex-dialog.cpp
@@ -7,10 +7,7 @@ tobii_eyex_dialog::tobii_eyex_dialog()
connect(ui.buttonBox, &QDialogButtonBox::accepted, this, &tobii_eyex_dialog::do_ok);
connect(ui.buttonBox, &QDialogButtonBox::rejected, this, &tobii_eyex_dialog::do_cancel);
- ui.tracking_mode->addItem("Snap", tobii_snap);
- ui.tracking_mode->addItem("Accumulative", tobii_acc);
-
- tie_setting(s.mode, ui.tracking_mode);
+ //tie_setting(s.mode, ui.tracking_mode);
}
void tobii_eyex_dialog::do_ok()
diff --git a/tracker-tobii-eyex/tobii-eyex-dialog.ui b/tracker-tobii-eyex/tobii-eyex-dialog.ui
index a6aecafb..37451f06 100644
--- a/tracker-tobii-eyex/tobii-eyex-dialog.ui
+++ b/tracker-tobii-eyex/tobii-eyex-dialog.ui
@@ -6,8 +6,8 @@
<rect>
<x>0</x>
<y>0</y>
- <width>659</width>
- <height>471</height>
+ <width>184</width>
+ <height>35</height>
</rect>
</property>
<property name="windowTitle">
@@ -22,447 +22,6 @@
<number>4</number>
</property>
<item row="0" column="0">
- <widget class="QGroupBox" name="groupBox">
- <property name="sizePolicy">
- <sizepolicy hsizetype="Minimum" vsizetype="Maximum">
- <horstretch>0</horstretch>
- <verstretch>0</verstretch>
- </sizepolicy>
- </property>
- <property name="title">
- <string>Tracking settings</string>
- </property>
- <layout class="QVBoxLayout" name="verticalLayout">
- <item>
- <widget class="QLabel" name="label_2">
- <property name="sizePolicy">
- <sizepolicy hsizetype="Expanding" vsizetype="Maximum">
- <horstretch>0</horstretch>
- <verstretch>0</verstretch>
- </sizepolicy>
- </property>
- <property name="minimumSize">
- <size>
- <width>617</width>
- <height>0</height>
- </size>
- </property>
- <property name="text">
- <string>Accumulative mode shifts the view toward a target that may be offscreen then fixes upon it.
-On the other hand, the snap mode allows for a quick glance outside the field of vision.</string>
- </property>
- <property name="textFormat">
- <enum>Qt::PlainText</enum>
- </property>
- <property name="wordWrap">
- <bool>true</bool>
- </property>
- </widget>
- </item>
- <item>
- <widget class="QFrame" name="frame">
- <property name="sizePolicy">
- <sizepolicy hsizetype="Preferred" vsizetype="Maximum">
- <horstretch>0</horstretch>
- <verstretch>0</verstretch>
- </sizepolicy>
- </property>
- <property name="frameShape">
- <enum>QFrame::NoFrame</enum>
- </property>
- <property name="frameShadow">
- <enum>QFrame::Raised</enum>
- </property>
- <layout class="QGridLayout" name="gridLayout">
- <property name="leftMargin">
- <number>4</number>
- </property>
- <property name="topMargin">
- <number>4</number>
- </property>
- <property name="rightMargin">
- <number>4</number>
- </property>
- <property name="bottomMargin">
- <number>4</number>
- </property>
- <property name="horizontalSpacing">
- <number>9</number>
- </property>
- <property name="verticalSpacing">
- <number>4</number>
- </property>
- <item row="0" column="0">
- <widget class="QLabel" name="label">
- <property name="text">
- <string>Tracking mode</string>
- </property>
- </widget>
- </item>
- <item row="0" column="1">
- <widget class="QComboBox" name="tracking_mode">
- <property name="sizePolicy">
- <sizepolicy hsizetype="Maximum" vsizetype="Maximum">
- <horstretch>0</horstretch>
- <verstretch>0</verstretch>
- </sizepolicy>
- </property>
- </widget>
- </item>
- <item row="0" column="2">
- <spacer name="horizontalSpacer">
- <property name="orientation">
- <enum>Qt::Horizontal</enum>
- </property>
- <property name="sizeHint" stdset="0">
- <size>
- <width>10</width>
- <height>0</height>
- </size>
- </property>
- </spacer>
- </item>
- </layout>
- </widget>
- </item>
- </layout>
- </widget>
- </item>
- <item row="1" column="0">
- <widget class="QGroupBox" name="groupBox_2">
- <property name="sizePolicy">
- <sizepolicy hsizetype="Minimum" vsizetype="Maximum">
- <horstretch>0</horstretch>
- <verstretch>0</verstretch>
- </sizepolicy>
- </property>
- <property name="title">
- <string>Accumulative mode settings</string>
- </property>
- <layout class="QGridLayout" name="gridLayout_2">
- <item row="0" column="0">
- <widget class="QLabel" name="label_3">
- <property name="sizePolicy">
- <sizepolicy hsizetype="Maximum" vsizetype="Maximum">
- <horstretch>0</horstretch>
- <verstretch>0</verstretch>
- </sizepolicy>
- </property>
- <property name="text">
- <string>Screen edge length</string>
- </property>
- </widget>
- </item>
- <item row="0" column="1">
- <widget class="QSlider" name="acc_inv_deadzone_slider">
- <property name="sizePolicy">
- <sizepolicy hsizetype="Expanding" vsizetype="Maximum">
- <horstretch>9</horstretch>
- <verstretch>0</verstretch>
- </sizepolicy>
- </property>
- <property name="minimum">
- <number>1</number>
- </property>
- <property name="maximum">
- <number>20</number>
- </property>
- <property name="pageStep">
- <number>1</number>
- </property>
- <property name="orientation">
- <enum>Qt::Horizontal</enum>
- </property>
- </widget>
- </item>
- <item row="0" column="2">
- <widget class="QLabel" name="acc_inv_deadzone_label">
- <property name="sizePolicy">
- <sizepolicy hsizetype="Expanding" vsizetype="Preferred">
- <horstretch>10</horstretch>
- <verstretch>0</verstretch>
- </sizepolicy>
- </property>
- <property name="text">
- <string/>
- </property>
- </widget>
- </item>
- <item row="1" column="0">
- <widget class="QLabel" name="label_4">
- <property name="sizePolicy">
- <sizepolicy hsizetype="Maximum" vsizetype="Maximum">
- <horstretch>0</horstretch>
- <verstretch>0</verstretch>
- </sizepolicy>
- </property>
- <property name="text">
- <string>Speed</string>
- </property>
- </widget>
- </item>
- <item row="2" column="0">
- <widget class="QLabel" name="label_6">
- <property name="sizePolicy">
- <sizepolicy hsizetype="Maximum" vsizetype="Maximum">
- <horstretch>0</horstretch>
- <verstretch>0</verstretch>
- </sizepolicy>
- </property>
- <property name="text">
- <string>Max yaw</string>
- </property>
- </widget>
- </item>
- <item row="1" column="1">
- <widget class="QSlider" name="acc_speed_slider">
- <property name="sizePolicy">
- <sizepolicy hsizetype="Expanding" vsizetype="Maximum">
- <horstretch>9</horstretch>
- <verstretch>0</verstretch>
- </sizepolicy>
- </property>
- <property name="maximum">
- <number>100</number>
- </property>
- <property name="pageStep">
- <number>1</number>
- </property>
- <property name="orientation">
- <enum>Qt::Horizontal</enum>
- </property>
- </widget>
- </item>
- <item row="3" column="0">
- <widget class="QLabel" name="label_7">
- <property name="sizePolicy">
- <sizepolicy hsizetype="Maximum" vsizetype="Maximum">
- <horstretch>0</horstretch>
- <verstretch>0</verstretch>
- </sizepolicy>
- </property>
- <property name="text">
- <string>Max pitch</string>
- </property>
- </widget>
- </item>
- <item row="2" column="1">
- <widget class="QComboBox" name="acc_max_yaw">
- <property name="sizePolicy">
- <sizepolicy hsizetype="Maximum" vsizetype="Maximum">
- <horstretch>0</horstretch>
- <verstretch>0</verstretch>
- </sizepolicy>
- </property>
- </widget>
- </item>
- <item row="3" column="1">
- <widget class="QComboBox" name="acc_max_pitch">
- <property name="sizePolicy">
- <sizepolicy hsizetype="Maximum" vsizetype="Maximum">
- <horstretch>0</horstretch>
- <verstretch>0</verstretch>
- </sizepolicy>
- </property>
- </widget>
- </item>
- <item row="4" column="0">
- <widget class="QLabel" name="label_11">
- <property name="sizePolicy">
- <sizepolicy hsizetype="Maximum" vsizetype="Maximum">
- <horstretch>0</horstretch>
- <verstretch>0</verstretch>
- </sizepolicy>
- </property>
- <property name="text">
- <string>Position output</string>
- </property>
- </widget>
- </item>
- <item row="4" column="1">
- <widget class="QCheckBox" name="acc_pos_output">
- <property name="sizePolicy">
- <sizepolicy hsizetype="Maximum" vsizetype="Maximum">
- <horstretch>0</horstretch>
- <verstretch>0</verstretch>
- </sizepolicy>
- </property>
- <property name="text">
- <string>Enabled</string>
- </property>
- </widget>
- </item>
- </layout>
- </widget>
- </item>
- <item row="2" column="0">
- <widget class="QGroupBox" name="groupBox_3">
- <property name="sizePolicy">
- <sizepolicy hsizetype="Minimum" vsizetype="Maximum">
- <horstretch>0</horstretch>
- <verstretch>0</verstretch>
- </sizepolicy>
- </property>
- <property name="title">
- <string>Snap mode settings</string>
- </property>
- <layout class="QGridLayout" name="gridLayout_3">
- <item row="2" column="1" rowspan="2">
- <widget class="QComboBox" name="snap_max_yaw">
- <property name="sizePolicy">
- <sizepolicy hsizetype="Maximum" vsizetype="Maximum">
- <horstretch>0</horstretch>
- <verstretch>0</verstretch>
- </sizepolicy>
- </property>
- </widget>
- </item>
- <item row="3" column="0" rowspan="2">
- <widget class="QLabel" name="label_10">
- <property name="sizePolicy">
- <sizepolicy hsizetype="Maximum" vsizetype="Maximum">
- <horstretch>0</horstretch>
- <verstretch>0</verstretch>
- </sizepolicy>
- </property>
- <property name="text">
- <string>Max pitch</string>
- </property>
- </widget>
- </item>
- <item row="2" column="0">
- <widget class="QLabel" name="label_9">
- <property name="sizePolicy">
- <sizepolicy hsizetype="Maximum" vsizetype="Maximum">
- <horstretch>0</horstretch>
- <verstretch>0</verstretch>
- </sizepolicy>
- </property>
- <property name="text">
- <string>Max yaw</string>
- </property>
- </widget>
- </item>
- <item row="1" column="0">
- <widget class="QLabel" name="label_8">
- <property name="sizePolicy">
- <sizepolicy hsizetype="Maximum" vsizetype="Maximum">
- <horstretch>0</horstretch>
- <verstretch>0</verstretch>
- </sizepolicy>
- </property>
- <property name="text">
- <string>Speed</string>
- </property>
- </widget>
- </item>
- <item row="0" column="1">
- <widget class="QSlider" name="snap_inv_deazone_slider">
- <property name="sizePolicy">
- <sizepolicy hsizetype="Expanding" vsizetype="Maximum">
- <horstretch>8</horstretch>
- <verstretch>0</verstretch>
- </sizepolicy>
- </property>
- <property name="minimum">
- <number>1</number>
- </property>
- <property name="maximum">
- <number>20</number>
- </property>
- <property name="pageStep">
- <number>1</number>
- </property>
- <property name="orientation">
- <enum>Qt::Horizontal</enum>
- </property>
- </widget>
- </item>
- <item row="4" column="1">
- <widget class="QComboBox" name="snap_max_pitch">
- <property name="sizePolicy">
- <sizepolicy hsizetype="Maximum" vsizetype="Maximum">
- <horstretch>0</horstretch>
- <verstretch>0</verstretch>
- </sizepolicy>
- </property>
- </widget>
- </item>
- <item row="0" column="2">
- <widget class="QLabel" name="snap_inv_deadzone_label">
- <property name="sizePolicy">
- <sizepolicy hsizetype="Preferred" vsizetype="Preferred">
- <horstretch>10</horstretch>
- <verstretch>0</verstretch>
- </sizepolicy>
- </property>
- <property name="text">
- <string/>
- </property>
- </widget>
- </item>
- <item row="1" column="1">
- <widget class="QSlider" name="snap_speed_slider">
- <property name="sizePolicy">
- <sizepolicy hsizetype="Expanding" vsizetype="Maximum">
- <horstretch>8</horstretch>
- <verstretch>0</verstretch>
- </sizepolicy>
- </property>
- <property name="maximum">
- <number>100</number>
- </property>
- <property name="pageStep">
- <number>1</number>
- </property>
- <property name="orientation">
- <enum>Qt::Horizontal</enum>
- </property>
- </widget>
- </item>
- <item row="0" column="0">
- <widget class="QLabel" name="label_5">
- <property name="sizePolicy">
- <sizepolicy hsizetype="Maximum" vsizetype="Maximum">
- <horstretch>0</horstretch>
- <verstretch>0</verstretch>
- </sizepolicy>
- </property>
- <property name="text">
- <string>Screen edge length</string>
- </property>
- </widget>
- </item>
- <item row="5" column="1">
- <widget class="QCheckBox" name="snap_pos_output">
- <property name="sizePolicy">
- <sizepolicy hsizetype="Maximum" vsizetype="Maximum">
- <horstretch>0</horstretch>
- <verstretch>0</verstretch>
- </sizepolicy>
- </property>
- <property name="text">
- <string>Enabled</string>
- </property>
- </widget>
- </item>
- <item row="5" column="0">
- <widget class="QLabel" name="label_12">
- <property name="sizePolicy">
- <sizepolicy hsizetype="Maximum" vsizetype="Maximum">
- <horstretch>0</horstretch>
- <verstretch>0</verstretch>
- </sizepolicy>
- </property>
- <property name="text">
- <string>Position output</string>
- </property>
- </widget>
- </item>
- </layout>
- </widget>
- </item>
- <item row="3" column="0">
<widget class="QDialogButtonBox" name="buttonBox">
<property name="sizePolicy">
<sizepolicy hsizetype="Minimum" vsizetype="Maximum">
@@ -479,6 +38,10 @@ On the other hand, the snap mode allows for a quick glance outside the field of
</widget>
<resources>
<include location="tobii-eyex-res.qrc"/>
+ <include location="tobii-eyex-res.qrc"/>
+ <include location="tobii-eyex-res.qrc"/>
+ <include location="tobii-eyex-res.qrc"/>
+ <include location="tobii-eyex-res.qrc"/>
</resources>
<connections/>
</ui>
diff --git a/tracker-tobii-eyex/tobii-eyex.cpp b/tracker-tobii-eyex/tobii-eyex.cpp
index 8f2edd62..af0d0c05 100644
--- a/tracker-tobii-eyex/tobii-eyex.cpp
+++ b/tracker-tobii-eyex/tobii-eyex.cpp
@@ -1,6 +1,7 @@
#include "tobii-eyex.hpp"
#include "compat/math-imports.hpp"
+#include <tuple>
#include <cstdlib>
#include <cstdio>
@@ -32,17 +33,7 @@ static inline tobii_eyex_tracker& to_self(TX_USERPARAM param)
return *reinterpret_cast<tobii_eyex_tracker*>(param);
}
-tobii_eyex_tracker::tobii_eyex_tracker() :
- dev_ctx(TX_EMPTY_HANDLE),
- conn_state_changed_ticket(TX_INVALID_TICKET),
- event_handler_ticket(TX_INVALID_TICKET),
- state_snapshot(TX_EMPTY_HANDLE),
- display_state(TX_EMPTY_HANDLE),
- yaw(0),
- pitch(0),
- do_center(false)
-{
-}
+tobii_eyex_tracker::tobii_eyex_tracker() = default;
void tobii_eyex_tracker::call_tx_deinit()
{
@@ -54,12 +45,12 @@ tobii_eyex_tracker::~tobii_eyex_tracker()
{
dbg_verbose("dtor");
- (void) txDisableConnection(dev_ctx);
+ (void) txDisableConnection(ctx);
(void) txReleaseObject(&state_snapshot);
bool status = true;
- status &= txShutdownContext(dev_ctx, TX_CLEANUPTIMEOUT_FORCEIMMEDIATE, TX_FALSE) == TX_RESULT_OK;
- status &= txReleaseContext(&dev_ctx) == TX_RESULT_OK;
+ status &= txShutdownContext(ctx, TX_CLEANUPTIMEOUT_FORCEIMMEDIATE, TX_FALSE) == TX_RESULT_OK;
+ status &= txReleaseContext(&ctx) == TX_RESULT_OK;
// the API cleanup function needs to be called exactly once over image lifetime.
// client software communicates with a service and a desktop program.
@@ -129,7 +120,7 @@ void tobii_eyex_tracker::snapshot_committed_handler(TX_CONSTHANDLE async_data_ha
dbg_notice("snapshot bad result code") << result;
}
-void tobii_eyex_tracker::connection_state_change_handler(TX_CONNECTIONSTATE state, TX_USERPARAM param)
+void tobii_eyex_tracker::state_change_handler(TX_CONNECTIONSTATE state, TX_USERPARAM param)
{
tobii_eyex_tracker& self = to_self(param);
@@ -142,7 +133,7 @@ void tobii_eyex_tracker::connection_state_change_handler(TX_CONNECTIONSTATE stat
dbg_notice("connected but failed to initialize data stream");
else
{
- txGetStateAsync(self.dev_ctx, TX_STATEPATH_EYETRACKINGSCREENBOUNDS, display_state_handler, param);
+ txGetStateAsync(self.ctx, TX_STATEPATH_EYETRACKINGSCREENBOUNDS, display_state_handler, param);
dbg_notice("connected, data stream ok");
}
}
@@ -222,11 +213,11 @@ module_status tobii_eyex_tracker::start_tracker(QFrame*)
bool status = true;
status &= txInitializeEyeX(TX_EYEXCOMPONENTOVERRIDEFLAG_NONE, nullptr, nullptr, nullptr, nullptr) == TX_RESULT_OK;
- status &= txCreateContext(&dev_ctx, TX_FALSE) == TX_RESULT_OK;
- status &= register_state_snapshot(dev_ctx, &state_snapshot);
- status &= txRegisterConnectionStateChangedHandler(dev_ctx, &conn_state_changed_ticket, connection_state_change_handler, reinterpret_cast<TX_USERPARAM>(this)) == TX_RESULT_OK;
- status &= txRegisterEventHandler(dev_ctx, &event_handler_ticket, event_handler, reinterpret_cast<TX_USERPARAM>(this)) == TX_RESULT_OK;
- status &= txEnableConnection(dev_ctx) == TX_RESULT_OK;
+ status &= txCreateContext(&ctx, TX_FALSE) == TX_RESULT_OK;
+ status &= register_state_snapshot(ctx, &state_snapshot);
+ status &= txRegisterConnectionStateChangedHandler(ctx, &state_changed_ticket, state_change_handler, (TX_USERPARAM)this) == TX_RESULT_OK;
+ status &= txRegisterEventHandler(ctx, &event_handler_ticket, event_handler, (TX_USERPARAM)this) == TX_RESULT_OK;
+ status &= txEnableConnection(ctx) == TX_RESULT_OK;
if (!status)
return error(tr("Connection can't be established. device missing?"));
@@ -234,78 +225,15 @@ module_status tobii_eyex_tracker::start_tracker(QFrame*)
return status_ok();
}
-tobii_eyex_tracker::num tobii_eyex_tracker::gain(num x)
+bool tobii_eyex_tracker::center()
{
- return 1;
+ do_center = true;
+ return true;
}
-static inline double signum(double x)
-{
- return !(x < 0) - (x < 0);
-}
-
-void tobii_eyex_tracker::data(double* data)
-{
- TX_REAL px, py, dw, dh, x_, y_;
- bool fresh;
-
- {
- QMutexLocker l(&global_state_mtx);
-
- if (!dev_state.is_valid())
- return;
-
- px = dev_state.px;
- py = dev_state.py;
- dw = dev_state.display_res_x;
- dh = dev_state.display_res_y;
-
- fresh = dev_state.fresh;
- dev_state.fresh = false;
- }
-
- x_ = (px-dw/2.) / (dw/2.);
- y_ = (py-dh/2.) / (dh/2.);
+settings::settings() : opts("tobii-eyex") {}
- data[TX] = x_ * 50;
- data[TY] = y_ * -50;
-
- if (fresh)
- {
- const double dt = t.elapsed_seconds();
- t.start();
-
- using std::fabs;
-
- constexpr double max_yaw = 45, max_pitch = 30;
- constexpr double c_yaw = 3;
- constexpr double c_pitch = c_yaw * max_pitch / max_yaw;
-
- const double yaw_delta = gain(fabs(x_)) * signum(x_) * c_yaw * dt;
- const double pitch_delta = gain(fabs(y_)) * signum(y_) * c_pitch * dt;
-
- yaw += yaw_delta;
- pitch += pitch_delta;
-
- yaw = clamp(yaw, -max_yaw, max_yaw);
- pitch = clamp(pitch, -max_pitch, max_pitch);
- }
-
- if (do_center)
- {
- do_center = false;
- yaw = 0;
- pitch = 0;
- }
-
- data[Yaw] = yaw;
- data[Pitch] = pitch;
- data[Roll] = 0;
- data[TZ] = 0; // XXX TODO
-
- // tan(x) in 0->.7 is almost linear. we don't need to adjust.
- // .7 is 40 degrees which is already quite a lot from the monitor.
-}
+state::state() = default;
#include "tobii-eyex-dialog.hpp"
diff --git a/tracker-tobii-eyex/tobii-eyex.hpp b/tracker-tobii-eyex/tobii-eyex.hpp
index 84407930..def2ea2e 100644
--- a/tracker-tobii-eyex/tobii-eyex.hpp
+++ b/tracker-tobii-eyex/tobii-eyex.hpp
@@ -23,6 +23,20 @@ using namespace options;
#include <QObject>
#include <QMutex>
+//using real = TX_REAL;
+using real = double;
+
+struct state
+{
+ real display_res_x = -1, display_res_y = -1;
+ real px = -1, py = -1;
+ real last_timestamp = -1;
+ bool fresh = false;
+
+ state();
+ bool is_valid() const { return !(display_res_x < 0 || px < 0); }
+};
+
class tobii_eyex_tracker : public TR, public ITracker
{
Q_OBJECT
@@ -30,13 +44,9 @@ class tobii_eyex_tracker : public TR, public ITracker
public:
tobii_eyex_tracker();
~tobii_eyex_tracker() override;
- module_status start_tracker(QFrame *) override;
+ module_status start_tracker(QFrame*) override;
void data(double *data) override;
- bool center() override
- {
- do_center = true;
- return true;
- }
+ bool center() override;
private:
static constexpr inline const char* const client_id = "opentrack-tobii-eyex";
@@ -44,47 +54,36 @@ private:
static bool register_state_snapshot(TX_CONTEXTHANDLE ctx, TX_HANDLE* state_snapshot_ptr);
static std::atomic_flag atexit_done;
- static void TX_CALLCONVENTION connection_state_change_handler(TX_CONNECTIONSTATE state, TX_USERPARAM param);
+ static void TX_CALLCONVENTION state_change_handler(TX_CONNECTIONSTATE state, TX_USERPARAM param);
static void TX_CALLCONVENTION event_handler(TX_CONSTHANDLE async_data_handle, TX_USERPARAM param);
void gaze_data_handler(TX_HANDLE gaze_data_handle);
static void TX_CALLCONVENTION snapshot_committed_handler(TX_CONSTHANDLE async_data_handle, TX_USERPARAM param);
static void TX_CALLCONVENTION display_state_handler(TX_CONSTHANDLE async_data_handle, TX_USERPARAM param);
void process_display_state(TX_HANDLE display_state_handle);
- using num = double;
+ real gain(real x);
- num gain(num x);
+ state dev_state;
+ real yaw = 0, pitch = 0;
- TX_CONTEXTHANDLE dev_ctx;
- TX_TICKET conn_state_changed_ticket;
- TX_TICKET event_handler_ticket;
- TX_HANDLE state_snapshot;
- TX_HANDLE display_state;
+ TX_CONTEXTHANDLE ctx = TX_EMPTY_HANDLE;
+ TX_TICKET state_changed_ticket = TX_INVALID_TICKET;
+ TX_TICKET event_handler_ticket = TX_INVALID_TICKET;
+ TX_HANDLE state_snapshot = TX_EMPTY_HANDLE;
+ TX_HANDLE display_state = TX_EMPTY_HANDLE;
QMutex global_state_mtx;
settings s;
Timer t;
- struct state
- {
- TX_REAL display_res_x, display_res_y;
- TX_REAL px, py;
- TX_REAL last_timestamp;
- bool fresh;
-
- state() : display_res_x(-1), display_res_y(-1), px(-1), py(-1), last_timestamp(0), fresh(false) {}
- bool is_valid() const { return !(display_res_x < 0 || px < 0); }
- } dev_state;
-
- double yaw, pitch;
- std::atomic<bool> do_center;
+ std::atomic<bool> do_center = false;
};
class tobii_eyex_metadata : public Metadata
{
Q_OBJECT
- QString name() { return QString("Tobii EyeX"); }
- QIcon icon() { return QIcon(":/images/tobii-eyex-logo.png"); }
+ QString name() override { return QString("Tobii EyeX"); }
+ QIcon icon() override { return QIcon(":/images/tobii-eyex-logo.png"); }
};
diff --git a/tracker-tobii-eyex/tobii-settings.hpp b/tracker-tobii-eyex/tobii-settings.hpp
index 49b9cae8..6101a28f 100644
--- a/tracker-tobii-eyex/tobii-settings.hpp
+++ b/tracker-tobii-eyex/tobii-settings.hpp
@@ -21,6 +21,7 @@ enum max_pitch
struct settings final : public opts
{
+#if 0
value<tobii_mode> mode { b, "mode", tobii_snap };
value<slider_value> snap_speed {b, "snap-speed", { .1, .05, 1 }},
@@ -28,9 +29,15 @@ struct settings final : public opts
value<slider_value> acc_speed {b, "acc-speed", { .1, .05, 1 }},
acc_dz_len {b, "acc-screen-edge-length", { .1, .1, 1 }};
value<max_yaw> snap_yaw {b, "snap-max-yaw", y20},
- acc_yaw {b, "acc-max-yaw", y20};
value<max_pitch> snap_pitch {b, "snap-max-pitch", p15},
acc_pitch {b, "acc-max-pitch", p15};
+ acc_yaw {b, "acc-max-yaw", y20};
+#endif
+ value<slider_value> acc_speed { b, "acc-max-speed-deg", { 3, 1, 10 } };
+ value<slider_value> acc_dz { b, "acc-deadzone", { .15, .0, .3 } };
- settings() : opts("tobii-eyex") {}
+ value<slider_value> acc_max_yaw { b, "acc-max-yaw", { 30, 15, 45} },
+ acc_max_pitch { b, "acc-max-pitch", { 30, 15, 45 } };
+
+ settings();
};