summaryrefslogtreecommitdiffhomepage
path: root/opentrack-logic
diff options
context:
space:
mode:
Diffstat (limited to 'opentrack-logic')
-rw-r--r--opentrack-logic/main-settings.hpp6
-rw-r--r--opentrack-logic/tracker.cpp33
-rw-r--r--opentrack-logic/tracker.h7
-rw-r--r--opentrack-logic/tracklogger.cpp33
-rw-r--r--opentrack-logic/tracklogger.hpp53
-rw-r--r--opentrack-logic/work.cpp43
-rw-r--r--opentrack-logic/work.hpp8
7 files changed, 177 insertions, 6 deletions
diff --git a/opentrack-logic/main-settings.hpp b/opentrack-logic/main-settings.hpp
index a7dcd11c..81eb99cf 100644
--- a/opentrack-logic/main-settings.hpp
+++ b/opentrack-logic/main-settings.hpp
@@ -73,6 +73,8 @@ struct main_settings
key_opts key_start_tracking, key_stop_tracking, key_toggle_tracking, key_restart_tracking;
key_opts key_center, key_toggle, key_zero;
key_opts key_toggle_press, key_zero_press;
+ value<bool> tracklogging_enabled;
+ value<QString> tracklogging_filename;
main_settings() :
b(bundle("opentrack-ui")),
a_x(b, "x", TX),
@@ -98,7 +100,9 @@ struct main_settings
key_toggle(b, "toggle"),
key_zero(b, "zero"),
key_toggle_press(b, "toggle-press"),
- key_zero_press(b, "zero-press")
+ key_zero_press(b, "zero-press"),
+ tracklogging_enabled(b, "tracklogging-enabled", false),
+ tracklogging_filename(b, "tracklogging-filename", QString())
{
}
};
diff --git a/opentrack-logic/tracker.cpp b/opentrack-logic/tracker.cpp
index a1f206a1..f29e3100 100644
--- a/opentrack-logic/tracker.cpp
+++ b/opentrack-logic/tracker.cpp
@@ -21,7 +21,7 @@
# include <windows.h>
#endif
-Tracker::Tracker(Mappings &m, SelectedLibraries &libs) :
+Tracker::Tracker(Mappings &m, SelectedLibraries &libs, TrackLogger &logger) :
m(m),
newpose {0,0,0, 0,0,0},
centerp(s.center_at_startup),
@@ -29,6 +29,7 @@ Tracker::Tracker(Mappings &m, SelectedLibraries &libs) :
zero_(false),
should_quit(false),
libs(libs),
+ logger(logger),
r_b(get_camera_offset_matrix().t()),
t_b {0,0,0}
{
@@ -134,6 +135,8 @@ void Tracker::logic()
raw(i) = newpose[i];
}
+ logger.write_pose(raw); // raw
+
if (is_nan(raw))
raw = last_raw;
@@ -207,10 +210,13 @@ void Tracker::logic()
}
}
+ logger.write_pose(value); // "corrected" - after various transformations to account for camera position
+
// whenever something can corrupt its internal state due to nan/inf, elide the call
if (is_nan(value))
{
nan = true;
+ logger.write_pose(value); // "filtered"
}
else
{
@@ -220,6 +226,7 @@ void Tracker::logic()
if (libs.pFilter)
libs.pFilter->filter(tmp, value);
}
+ logger.write_pose(value); // "filtered"
// CAVEAT rotation only, due to tcomp
for (int i = 3; i < 6; i++)
@@ -256,6 +263,8 @@ void Tracker::logic()
for (int i = 0; i < 3; i++)
value(i) = map(value(i), m(i));
+ logger.write_pose(value); // "mapped"
+
if (nan)
{
value = last_mapped;
@@ -265,6 +274,8 @@ void Tracker::logic()
(void) map(value(i), m(i));
}
+ logger.next_line();
+
libs.pProtocol->pose(value);
last_mapped = value;
@@ -283,8 +294,28 @@ void Tracker::run()
(void) timeBeginPeriod(1);
#endif
+ {
+ const char* posechannels[6] = { "TX", "TY", "TZ", "Yaw", "Pitch", "Roll" };
+ const char* datachannels[5] = { "dt", "raw", "corrected", "filtered", "mapped" };
+ logger.write(datachannels[0]);
+ char buffer[128];
+ for (int j = 1; j < 5; ++j)
+ {
+ for (int i = 0; i < 6; ++i)
+ {
+ snprintf(buffer, 128, "%s%s", datachannels[j], posechannels[i]);
+ logger.write(buffer);
+ }
+ }
+ }
+ logger.next_line();
+
while (!should_quit)
{
+ {
+ double dt = t.elapsed_seconds();
+ logger.write(&dt, 1);
+ }
t.start();
double tmp[6] {0,0,0, 0,0,0};
diff --git a/opentrack-logic/tracker.h b/opentrack-logic/tracker.h
index fae8bd9e..b4d39a44 100644
--- a/opentrack-logic/tracker.h
+++ b/opentrack-logic/tracker.h
@@ -20,6 +20,7 @@
#include "spline-widget/functionconfig.h"
#include "main-settings.hpp"
#include "opentrack-compat/options.hpp"
+#include "tracklogger.hpp"
#include <QMutex>
#include <QThread>
@@ -62,6 +63,10 @@ private:
volatile bool zero_;
volatile bool should_quit;
SelectedLibraries const& libs;
+ // The owner of the reference is the main window.
+ // This design might be usefull if we decide later on to swap out
+ // the logger while the tracker is running.
+ TrackLogger &logger;
using rmat = euler::rmat;
using euler_t = euler::euler_t;
@@ -78,7 +83,7 @@ private:
static constexpr double r2d = 180. / OPENTRACK_PI;
static constexpr double d2r = OPENTRACK_PI / 180.;
public:
- Tracker(Mappings& m, SelectedLibraries& libs);
+ Tracker(Mappings& m, SelectedLibraries& libs, TrackLogger &logger);
~Tracker();
rmat get_camera_offset_matrix();
diff --git a/opentrack-logic/tracklogger.cpp b/opentrack-logic/tracklogger.cpp
new file mode 100644
index 00000000..f007c2bc
--- /dev/null
+++ b/opentrack-logic/tracklogger.cpp
@@ -0,0 +1,33 @@
+#include "tracklogger.hpp"
+#include "tracker.h"
+
+void TrackLoggerCSV::handle_first_col_sep()
+{
+ if (!first_col)
+ out.put(',');
+ first_col = false;
+}
+
+void TrackLoggerCSV::write(const char *s)
+{
+ handle_first_col_sep();
+ out << s;
+}
+
+
+void TrackLoggerCSV::write(const double *p, int n)
+{
+ handle_first_col_sep();
+ for (int i = 0; i < n-1; ++i)
+ {
+ out << p[i];
+ out.put(',');
+ }
+ out << p[n-1];
+}
+
+void TrackLoggerCSV::next_line()
+{
+ out << std::endl;
+ first_col = true;
+} \ No newline at end of file
diff --git a/opentrack-logic/tracklogger.hpp b/opentrack-logic/tracklogger.hpp
new file mode 100644
index 00000000..65128d48
--- /dev/null
+++ b/opentrack-logic/tracklogger.hpp
@@ -0,0 +1,53 @@
+#pragma once
+#include "main-settings.hpp"
+#include "opentrack-compat/options.hpp"
+
+#include <fstream>
+#include <QString>
+#include <QMessageBox>
+#include <QWidget>
+
+class OPENTRACK_LOGIC_EXPORT TrackLogger
+{
+public:
+ TrackLogger()
+ {
+ }
+
+ virtual void write(const char *)
+ {
+ }
+
+ virtual void write(const double *, int n)
+ {
+ }
+
+ virtual void next_line()
+ {
+ }
+
+ void write_pose(const double *p)
+ {
+ write(p, 6);
+ }
+};
+
+
+class OPENTRACK_LOGIC_EXPORT TrackLoggerCSV : public TrackLogger
+{
+ std::ofstream out;
+ bool first_col;
+ inline void handle_first_col_sep();
+public:
+ TrackLoggerCSV(const QString &filename) : TrackLogger(),
+ first_col(true)
+ {
+ out.open(filename.toStdString());
+ }
+
+ bool is_open() const { return out.is_open(); }
+ virtual void write(const char *s);
+ virtual void write(const double *p, int n);
+ virtual void next_line();
+};
+
diff --git a/opentrack-logic/work.cpp b/opentrack-logic/work.cpp
index 820112bf..8d00270b 100644
--- a/opentrack-logic/work.cpp
+++ b/opentrack-logic/work.cpp
@@ -1,9 +1,50 @@
#include "work.hpp"
+#include <QMessageBox>
+
+
+std::shared_ptr<TrackLogger> Work::make_logger(const main_settings &s)
+{
+ if (s.tracklogging_enabled)
+ {
+ if (static_cast<QString>(s.tracklogging_filename).isEmpty())
+ {
+ QMessageBox::warning(nullptr, "Logging Error",
+ "No filename given for track logging. Proceeding without logging.",
+ QMessageBox::Ok,
+ QMessageBox::NoButton);
+ }
+ else
+ {
+ auto logger = std::make_shared<TrackLoggerCSV>(s.tracklogging_filename);
+ if (!logger->is_open())
+ {
+ logger = nullptr;
+ QMessageBox::warning(nullptr, "Logging Error",
+ "Unable to open file: " + s.tracklogging_filename + ". Proceeding without logging.",
+ QMessageBox::Ok,
+ QMessageBox::NoButton);
+ }
+ else
+ {
+ /* As this function has the potential to fill up the hard drive
+ of the unwary with junk data, a warning is in order. */
+ QMessageBox::warning(nullptr, "Logging Active",
+ "Just a heads up. You are recoding pose data to " + s.tracklogging_filename + "!",
+ QMessageBox::Ok,
+ QMessageBox::NoButton);
+ return logger;
+ }
+ }
+ }
+ return std::make_shared<TrackLogger>();
+}
+
Work::Work(Mappings& m, SelectedLibraries& libs, WId handle) :
libs(libs),
- tracker(std::make_shared<Tracker>(m, libs)),
+ logger(make_logger(s)),
+ tracker(std::make_shared<Tracker>(m, libs, *logger)),
sc(std::make_shared<Shortcuts>()),
handle(handle),
keys {
diff --git a/opentrack-logic/work.hpp b/opentrack-logic/work.hpp
index 70322be2..4afb1da4 100644
--- a/opentrack-logic/work.hpp
+++ b/opentrack-logic/work.hpp
@@ -13,6 +13,7 @@
#include "tracker.h"
#include "shortcuts.h"
#include "export.hpp"
+#include "tracklogger.hpp"
#include <QObject>
#include <QFrame>
@@ -25,15 +26,18 @@ struct OPENTRACK_LOGIC_EXPORT Work
{
using fn_t = std::function<void(bool)>;
using key_tuple = std::tuple<key_opts&, fn_t, bool>;
-
+ main_settings s; // tracker needs settings, so settings must come before it
SelectedLibraries& libs;
+ std::shared_ptr<TrackLogger> logger; // must come before tracker, since tracker depends on it
std::shared_ptr<Tracker> tracker;
std::shared_ptr<Shortcuts> sc;
WId handle;
std::vector<key_tuple> keys;
- main_settings s;
Work(Mappings& m, SelectedLibraries& libs, WId handle);
~Work();
void reload_shortcuts();
+
+private:
+ std::shared_ptr<TrackLogger> make_logger(const main_settings &s);
};