Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
67 changes: 58 additions & 9 deletions mainwindow.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ static uint32_t samples_written = 0;

void push_tobii_gaze(TobiiResearchGazeData *g, void *gaze_stream) {
auto gs = reinterpret_cast<lsl::stream_outlet *>(gaze_stream);
/*
if (!g->left_eye.gaze_point.validity) {
g->left_eye.gaze_point.position_on_display_area.x = NAN;
g->left_eye.gaze_point.position_on_display_area.y = NAN;
Expand All @@ -51,19 +52,23 @@ void push_tobii_gaze(TobiiResearchGazeData *g, void *gaze_stream) {
g->right_eye.gaze_point.position_on_display_area.x = NAN;
g->right_eye.gaze_point.position_on_display_area.y = NAN;
}
const float sample[] = {g->left_eye.gaze_point.position_on_display_area.x,
g->left_eye.gaze_point.position_on_display_area.y,
*/
const float sample[] = {g->device_time_stamp,
g->system_time_stamp,
g->left_eye.gaze_point.validity ? g->left_eye.gaze_point.position_on_display_area.x : NAN,
g->left_eye.gaze_point.validity ? g->left_eye.gaze_point.position_on_display_area.y : NAN,
g->left_eye.pupil_data.validity ? g->left_eye.pupil_data.diameter : NAN,
g->right_eye.gaze_point.position_on_display_area.x,
g->right_eye.gaze_point.position_on_display_area.y,
g->right_eye.gaze_point.validity ? g->right_eye.gaze_point.position_on_display_area.x : NAN,
g->right_eye.gaze_point.validity ? g->right_eye.gaze_point.position_on_display_area.y : NAN,
g->right_eye.pupil_data.validity ? g->right_eye.pupil_data.diameter : NAN};
gs->push_sample(sample, g->system_time_stamp / 1000000.);
gs->push_sample(sample);
samples_written++;
};

MainWindow::MainWindow(QWidget *parent, const char *config_file)
: QMainWindow(parent), ui(new Ui::MainWindow) {
ui->setupUi(this);
connect(ui->address, &QLineEdit::textChanged, this, &MainWindow::refresh_samplingrate);
connect(ui->actionLoad_Configuration, &QAction::triggered, [this]() {
load_config(QFileDialog::getOpenFileName(
this, "Load Configuration File", "", "Configuration Files (*.cfg)"));
Expand All @@ -90,12 +95,19 @@ MainWindow::MainWindow(QWidget *parent, const char *config_file)
void MainWindow::load_config(const QString &filename) {
QSettings settings(filename, QSettings::Format::IniFormat);
ui->address->setText(settings.value("TobiiPro/address", "127.0.0.1").toString());
ui->samplingrate->setText(settings.value("TobiiPro/rate", "60").toString());
ui->participant->setText(settings.value("Participant/ID", "P0").toString());
}

void MainWindow::save_config(const QString &filename) {
QSettings settings(filename, QSettings::Format::IniFormat);
settings.beginGroup("TobiiPro");
settings.setValue("address", ui->address->text());
settings.setValue("rate", ui->samplingrate->text());
settings.endGroup();
settings.beginGroup("Participant");
settings.setValue("ID", ui->participant->text());
settings.endGroup();
}

void MainWindow::closeEvent(QCloseEvent *ev) {
Expand All @@ -120,22 +132,50 @@ void MainWindow::refresh_eyetrackers() {
}
}

void MainWindow::refresh_samplingrate() {
ui->samplingrateDropdown->clear();
QString address = ui->address->text();
try {

QByteArray addr = address.toLocal8Bit();
auto res = tobii_research_get_eyetracker(addr.constData(), &current_tracker);
if (res != TOBII_RESEARCH_STATUS_OK)
return;

TobiiResearchGazeOutputFrequencies* frequencies = NULL;
size_t i = 0;
int status = tobii_research_get_all_gaze_output_frequencies(current_tracker, &frequencies);
for (; i < frequencies->frequency_count; i++) {
ui->samplingrateDropdown->addItem(QString::number(frequencies->frequencies[i]));
}
}
catch (std::exception & e) {
QMessageBox::critical(
this, "Error", QStringLiteral("Error: ") + e.what(), QMessageBox::Ok);
}


}

void MainWindow::toggleRecording() {
if (!gaze_stream) {
ui->linkButton->setEnabled(false);
// === perform link action ===
QString participant = ui->participant->text();
QString address = ui->address->text();
QString ratestr = ui->samplingrate->text();
bool ok = false;
double rate = ratestr.toDouble(&ok);

try {
QByteArray addr = address.toLocal8Bit();
auto res = tobii_research_get_eyetracker(addr.constData(), &current_tracker);
if (res != TOBII_RESEARCH_STATUS_OK)
throw std::runtime_error("Could not connect: " + std::to_string(res));

const auto samplingrate = 600; // TODO
// Start LSL outlet
std::string streamname = "Tobii";
lsl::stream_info info(streamname, "Eyetracker", 6, samplingrate, lsl::cf_float32,
lsl::stream_info info(streamname+"-"+participant.toLocal8Bit().constData(), "Eyetracker", 8,rate, lsl::cf_float32,
streamname + "at_" + address.toStdString());

// append some meta-data
Expand All @@ -147,6 +187,14 @@ void MainWindow::toggleRecording() {
.append_child_value("precision", "24");

auto channels = info.desc().append_child("channels");
channels.append_child("channel")
.append_child_value("label", "device_ts")
.append_child_value("type", "timestamp")
.append_child_value("unit", "milliseconds");
channels.append_child("channel")
.append_child_value("label", "system_ts")
.append_child_value("type", "timestamp")
.append_child_value("unit", "milliseconds");
channels.append_child("channel")
.append_child_value("label", "left_x")
.append_child_value("eye", "left")
Expand Down Expand Up @@ -183,6 +231,7 @@ void MainWindow::toggleRecording() {
// reset the counter
samples_written = 0;

tobii_research_set_gaze_output_frequency(current_tracker, rate);
// subscribe to the stream
res = tobii_research_subscribe_to_gaze_data(
current_tracker, push_tobii_gaze, gaze_stream.get());
Expand All @@ -202,15 +251,15 @@ void MainWindow::toggleRecording() {
this, "Error", QStringLiteral("Error: ") + e.what(), QMessageBox::Ok);
}
ui->linkButton->setEnabled(true);
ui->linkButton->setText("Unlink");
ui->linkButton->setText("Stop stream");
} else {
// === perform unlink action ===
ui->linkButton->setEnabled(false);
tobii_research_unsubscribe_from_gaze_data(current_tracker, push_tobii_gaze);
gaze_stream.reset();
statusTimer.stop();
ui->linkButton->setEnabled(true);
ui->linkButton->setText("Link");
ui->linkButton->setText("Start stream");
}
}

Expand Down
1 change: 1 addition & 0 deletions mainwindow.h
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ private slots:
void closeEvent(QCloseEvent *ev) override;
void toggleRecording();
void refresh_eyetrackers();
void refresh_samplingrate();

private:
// function for loading / saving the config file
Expand Down
62 changes: 53 additions & 9 deletions mainwindow.ui
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@
<item row="2" column="0">
<widget class="QLabel" name="addressLabel">
<property name="text">
<string>Tobii Address</string>
<string>Selected Address</string>
</property>
</widget>
</item>
Expand All @@ -48,14 +48,14 @@
</widget>
</item>
<item row="3" column="0">
<widget class="QLabel" name="samplingrateLabel">
<widget class="QLabel" name="samplingrateDropdownLabel">
<property name="text">
<string>Samplingrate</string>
<string>Rate options</string>
</property>
</widget>
</item>
<item row="3" column="1">
<widget class="QComboBox" name="samplingrate">
<widget class="QComboBox" name="samplingrateDropdown">
<property name="sizePolicy">
<sizepolicy hsizetype="Expanding" vsizetype="Fixed">
<horstretch>0</horstretch>
Expand All @@ -67,7 +67,35 @@
</property>
</widget>
</item>
<item row="4" column="0" colspan="2">
<item row="4" column="0">
<widget class="QLabel" name="samplingrateLabel">
<property name="text">
<string>Selected rate</string>
</property>
</widget>
</item>
<item row="4" column="1">
<widget class="QLineEdit" name="samplingrate">
<property name="text">
<string> </string>
</property>
</widget>
</item>
<item row="5" column="0">
<widget class="QLabel" name="participantLabel">
<property name="text">
<string>Participant</string>
</property>
</widget>
</item>
<item row="5" column="1">
<widget class="QLineEdit" name="participant">
<property name="text">
<string> </string>
</property>
</widget>
</item>
<item row="6" column="0" colspan="2">
<widget class="QPushButton" name="linkButton">
<property name="sizePolicy">
<sizepolicy hsizetype="MinimumExpanding" vsizetype="Fixed">
Expand All @@ -76,11 +104,11 @@
</sizepolicy>
</property>
<property name="text">
<string>Link</string>
<string>Start stream</string>
</property>
</widget>
</item>
<item row="5" column="0" colspan="2">
<item row="7" column="0" colspan="2">
<widget class="QGroupBox" name="groupBox">
<property name="title">
<string>Streams to enable</string>
Expand All @@ -96,7 +124,7 @@
</layout>
</widget>
</item>
<item row="7" column="0">
<item row="9" column="0">
<widget class="QLabel" name="tobiilogo">
<property name="sizePolicy">
<sizepolicy hsizetype="Minimum" vsizetype="Minimum">
Expand All @@ -112,7 +140,7 @@
</property>
</widget>
</item>
<item row="7" column="1">
<item row="9" column="1">
<widget class="QLabel" name="poweredbytobii">
<property name="text">
<string>This application is
Expand Down Expand Up @@ -201,5 +229,21 @@ powered by Tobii</string>
</hint>
</hints>
</connection>
<connection>
<sender>samplingrateDropdown</sender>
<signal>activated(QString)</signal>
<receiver>samplingrate</receiver>
<slot>setText(QString)</slot>
<hints>
<hint type="sourcelabel">
<x>150</x>
<y>57</y>
</hint>
<hint type="destinationlabel">
<x>150</x>
<y>107</y>
</hint>
</hints>
</connection>
</connections>
</ui>