From 3a1f8606c5b415be00ebf21cd57f4fed6832b800 Mon Sep 17 00:00:00 2001 From: Tom Brazier Date: Tue, 30 May 2023 16:20:30 +0100 Subject: Picked a name - natural movement filter --- filter-nm/CMakeLists.txt | 1 + filter-nm/ftnoir_filter_nm.cpp | 48 +++ filter-nm/ftnoir_filter_nm.h | 93 ++++++ filter-nm/ftnoir_filter_nm_dialog.cpp | 88 +++++ filter-nm/ftnoir_nm_filtercontrols.ui | 610 ++++++++++++++++++++++++++++++++++ filter-nm/lang/nl_NL.ts | 78 +++++ filter-nm/lang/ru_RU.ts | 78 +++++ filter-nm/lang/stub.ts | 78 +++++ filter-nm/lang/zh_CN.ts | 78 +++++ 9 files changed, 1152 insertions(+) create mode 100644 filter-nm/CMakeLists.txt create mode 100644 filter-nm/ftnoir_filter_nm.cpp create mode 100644 filter-nm/ftnoir_filter_nm.h create mode 100644 filter-nm/ftnoir_filter_nm_dialog.cpp create mode 100644 filter-nm/ftnoir_nm_filtercontrols.ui create mode 100644 filter-nm/lang/nl_NL.ts create mode 100644 filter-nm/lang/ru_RU.ts create mode 100644 filter-nm/lang/stub.ts create mode 100644 filter-nm/lang/zh_CN.ts (limited to 'filter-nm') diff --git a/filter-nm/CMakeLists.txt b/filter-nm/CMakeLists.txt new file mode 100644 index 000000000..d98e90e21 --- /dev/null +++ b/filter-nm/CMakeLists.txt @@ -0,0 +1 @@ +otr_module(filter-tom) diff --git a/filter-nm/ftnoir_filter_nm.cpp b/filter-nm/ftnoir_filter_nm.cpp new file mode 100644 index 000000000..6bcfeae0f --- /dev/null +++ b/filter-nm/ftnoir_filter_nm.cpp @@ -0,0 +1,48 @@ +/* Copyright (c) 2023 Tom Brazier + * + * 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. + */ +#include "filter_tom.h" +#include "compat/math-imports.hpp" +#include "compat/macros.h" + +#include "api/plugin-api.hpp" +#include "opentrack/defs.hpp" + +#include + +tom::tom() +{ +} + +void tom::filter(const double* input, double* output) +{ + // order of axes: x, y, z, yaw, pitch, roll + if (unlikely(first_run)) + { + first_run = false; + t.start(); + + std::fill(speeds, speeds + 6, 0.0); + std::copy(input, input + 6, filtered_output); + } + else + { + const double dt = t.elapsed_seconds(); + t.start(); + + for (int i = 0; i < 6; i++) + { + double speed = (input[i] - last_input[i]) / dt; + speeds[i] += dt * (double)s.responsiveness[i] * (speed - speeds[i]); + filtered_output[i] += dt * (double)s.responsiveness[i] * min(1.0, abs(speeds[i]) / (double)s.drift_speeds[i]) * (input[i] - filtered_output[i]); + } + } + + std::copy(input, input + 6, last_input); + std::copy(filtered_output, filtered_output + 6, output); +} + +OPENTRACK_DECLARE_FILTER(tom, dialog_tom, tomDll) diff --git a/filter-nm/ftnoir_filter_nm.h b/filter-nm/ftnoir_filter_nm.h new file mode 100644 index 000000000..0f6d07c20 --- /dev/null +++ b/filter-nm/ftnoir_filter_nm.h @@ -0,0 +1,93 @@ +/* Copyright (c) 2023 Tom Brazier + * + * 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 "ui_tom_filtercontrols.h" + +#include "api/plugin-api.hpp" +#include "compat/timer.hpp" +#include "options/options.hpp" + +using namespace options; + +struct settings_tom : opts +{ + value responsiveness[6]; + value drift_speeds[6]; + + settings_tom() : + opts("tom-filter"), + responsiveness{ value(b, "x-responsiveness", { 10.0, .0, 20.0 }), + value(b, "y-responsiveness", { 10.0, .0, 20.0 }), + value(b, "z-responsiveness", { 10.0, .0, 20.0 }), + value(b, "yaw-responsiveness", { 10.0, .0, 20.0 }), + value(b, "pitch-responsiveness", { 10.0, .0, 20.0 }), + value(b, "roll-responsiveness", { 10.0, .0, 20.0 }) }, + drift_speeds{ value(b, "x-drift-speed", { 50.0, 1.0, 200.0 }), + value(b, "y-drift-speed", { 50.0, 1.0, 200.0 }), + value(b, "z-drift-speed", { 50.0, 1.0, 200.0 }), + value(b, "yaw-drift-speed", { 100.0, 1.0, 400.0 }), + value(b, "pitch-drift-speed", { 100.0, 1.0, 400.0 }), + value(b, "roll-drift-speed", { 100.0, 1.0, 400.0 }) } + { + } + + /* value kMinSmoothing, kMaxSmoothing, kSmoothingScaleCurve; + settings() + : opts("ewma-filter"), + kMinSmoothing(b, "min-smoothing", { .02, .01, 1 }), + kMaxSmoothing(b, "max-smoothing", { .7, .01, 1 }), + kSmoothingScaleCurve(b, "smoothing-scale-curve", { .8, .1, 5 }) + { + } +*/ +}; + +struct tom : IFilter +{ + tom(); + void filter(const double* input, double* output) override; + void center() override { first_run = true; } + module_status initialize() override { return status_ok(); } + +private: + double last_input[6]{}; + double speeds[6]{}; + double filtered_output[6]{}; + Timer t; + settings_tom s; + bool first_run = true; +}; + +class dialog_tom : public IFilterDialog +{ + Q_OBJECT +public: + dialog_tom(); + void register_filter(IFilter*) override {} + void unregister_filter() override {} + void save() override; + void reload() override; + bool embeddable() noexcept override { return true; } + void set_buttons_visible(bool x) override; + +private: + Ui::UICdialog_tom ui; + settings_tom s; + +private slots: + void doOK(); + void doCancel(); +}; + +class tomDll : public Metadata +{ + Q_OBJECT + + QString name() override { return tr("Tom"); } + QIcon icon() override { return QIcon(":/images/filter-16.png"); } +}; diff --git a/filter-nm/ftnoir_filter_nm_dialog.cpp b/filter-nm/ftnoir_filter_nm_dialog.cpp new file mode 100644 index 000000000..5a6ad3a42 --- /dev/null +++ b/filter-nm/ftnoir_filter_nm_dialog.cpp @@ -0,0 +1,88 @@ +/* Copyright (c) 2023 Tom Brazier + * + * 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. + */ +#include "filter_tom.h" + +using namespace options; + +dialog_tom::dialog_tom() +{ + ui.setupUi(this); + + tie_setting(s.responsiveness[0], ui.x_responsiveness_slider); + tie_setting(s.responsiveness[0], ui.x_responsiveness, [](double x) + { return QStringLiteral("%1").arg(x, 0, 'f', 2); }); + + tie_setting(s.responsiveness[1], ui.y_responsiveness_slider); + tie_setting(s.responsiveness[1], ui.y_responsiveness, [](double x) + { return QStringLiteral("%1").arg(x, 0, 'f', 2); }); + + tie_setting(s.responsiveness[2], ui.z_responsiveness_slider); + tie_setting(s.responsiveness[2], ui.z_responsiveness, [](double x) + { return QStringLiteral("%1").arg(x, 0, 'f', 2); }); + + tie_setting(s.responsiveness[3], ui.yaw_responsiveness_slider); + tie_setting(s.responsiveness[3], ui.yaw_responsiveness, [](double x) + { return QStringLiteral("%1").arg(x, 0, 'f', 2); }); + + tie_setting(s.responsiveness[4], ui.pitch_responsiveness_slider); + tie_setting(s.responsiveness[4], ui.pitch_responsiveness, [](double x) + { return QStringLiteral("%1").arg(x, 0, 'f', 2); }); + + tie_setting(s.responsiveness[5], ui.roll_responsiveness_slider); + tie_setting(s.responsiveness[5], ui.roll_responsiveness, [](double x) + { return QStringLiteral("%1").arg(x, 0, 'f', 2); }); + + tie_setting(s.drift_speeds[0], ui.x_drift_speed_slider); + tie_setting(s.drift_speeds[0], ui.x_drift_speed, [](double x) + { return QStringLiteral("%1").arg(x, 0, 'f', 2); }); + + tie_setting(s.drift_speeds[1], ui.y_drift_speed_slider); + tie_setting(s.drift_speeds[1], ui.y_drift_speed, [](double x) + { return QStringLiteral("%1").arg(x, 0, 'f', 2); }); + + tie_setting(s.drift_speeds[2], ui.z_drift_speed_slider); + tie_setting(s.drift_speeds[2], ui.z_drift_speed, [](double x) + { return QStringLiteral("%1").arg(x, 0, 'f', 2); }); + + tie_setting(s.drift_speeds[3], ui.yaw_drift_speed_slider); + tie_setting(s.drift_speeds[3], ui.yaw_drift_speed, [](double x) + { return QStringLiteral("%1").arg(x, 0, 'f', 2); }); + + tie_setting(s.drift_speeds[4], ui.pitch_drift_speed_slider); + tie_setting(s.drift_speeds[4], ui.pitch_drift_speed, [](double x) + { return QStringLiteral("%1").arg(x, 0, 'f', 2); }); + + tie_setting(s.drift_speeds[5], ui.roll_drift_speed_slider); + tie_setting(s.drift_speeds[5], ui.roll_drift_speed, [](double x) + { return QStringLiteral("%1").arg(x, 0, 'f', 2); }); +} + +void dialog_tom::doOK() +{ + save(); + close(); +} + +void dialog_tom::doCancel() +{ + close(); +} + +void dialog_tom::save() +{ + s.b->save(); +} + +void dialog_tom::reload() +{ + s.b->reload(); +} + +void dialog_tom::set_buttons_visible(bool x) +{ + ui.buttonBox->setVisible(x); +} diff --git a/filter-nm/ftnoir_nm_filtercontrols.ui b/filter-nm/ftnoir_nm_filtercontrols.ui new file mode 100644 index 000000000..1a135c1ed --- /dev/null +++ b/filter-nm/ftnoir_nm_filtercontrols.ui @@ -0,0 +1,610 @@ + + + UICdialog_tom + + + + 0 + 0 + 438 + 559 + + + + Dialog + + + + + + Responsiveness + + + + + + X + + + + + + + + 0 + 0 + + + + + 30 + 0 + + + + 10.0 + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + + + + + + 0 + 0 + + + + 40 + + + Qt::Horizontal + + + + + + + Y + + + + + + + + 30 + 0 + + + + 10.0 + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + + + + + 40 + + + Qt::Horizontal + + + + + + + Z + + + + + + + + 30 + 0 + + + + 10.0 + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + + + + + 40 + + + Qt::Horizontal + + + + + + + Yaw + + + + + + + + 30 + 0 + + + + 10.0 + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + + + + + 40 + + + Qt::Horizontal + + + + + + + Pitch + + + + + + + + 30 + 0 + + + + 10.0 + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + + + + + 40 + + + Qt::Horizontal + + + + + + + Roll + + + + + + + + 30 + 0 + + + + 10.0 + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + + + + + 40 + + + Qt::Horizontal + + + + + + + + + + + 0 + 0 + + + + Natural movement filter by Tom Brazier: Cancels higher frequency noise and the natural tendency for our heads to drift even when we think we are sitting still. + + + Qt::PlainText + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignTop + + + true + + + + + + + Drift speeds + + + + + + Z + + + + + + + 1 + + + 200 + + + Qt::Horizontal + + + + + + + Roll + + + + + + + + 30 + 0 + + + + 50 + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + + + + + °/s + + + + + + + mm/s + + + + + + + °/s + + + + + + + 1 + + + 200 + + + Qt::Horizontal + + + + + + + + 30 + 0 + + + + 50 + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + + + + + + 30 + 0 + + + + 100 + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + + + + + Y + + + + + + + + 30 + 0 + + + + 100 + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + + + + + Pitch + + + + + + + 1 + + + 400 + + + Qt::Horizontal + + + + + + + X + + + + + + + + 30 + 0 + + + + 100 + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + + + + + mm/s + + + + + + + mm/s + + + + + + + Yaw + + + + + + + + 0 + 0 + + + + 1 + + + 200 + + + Qt::Horizontal + + + + + + + °/s + + + + + + + 1 + + + 400 + + + Qt::Horizontal + + + + + + + 1 + + + 400 + + + Qt::Horizontal + + + + + + + + 0 + 0 + + + + + 30 + 0 + + + + 50 + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + + + + + + + + Qt::Horizontal + + + QDialogButtonBox::Cancel|QDialogButtonBox::Ok + + + + + + + Instructions: Set all sliders to minimum. Then on an axis by axis basis: First, increase responsiveness until the filter only just cancels jerkiness for faster head movements. Second, increase drift speed until the filter only just cancels drift movement when your head is still. + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignTop + + + true + + + + + + + Qt::Vertical + + + + 20 + 40 + + + + + + + + + + buttonBox + accepted() + UICdialog_tom + accept() + + + 248 + 254 + + + 157 + 274 + + + + + buttonBox + rejected() + UICdialog_tom + reject() + + + 316 + 260 + + + 286 + 274 + + + + + diff --git a/filter-nm/lang/nl_NL.ts b/filter-nm/lang/nl_NL.ts new file mode 100644 index 000000000..ce0aefe31 --- /dev/null +++ b/filter-nm/lang/nl_NL.ts @@ -0,0 +1,78 @@ + + + + + UICdialog_tom + + Dialog + + + + X + + + + Y + + + + Z + + + + Yaw + + + + Pitch + + + + Roll + + + + °/s + + + + mm/s + + + + Responsiveness + + + + 10.0 + + + + Drift speeds + + + + 50 + + + + 100 + + + + Natural movement filter: cancels higher frequency noise and the natural tendency for our heads to drift even when we think we are sitting still. + + + + Instructions: Set all sliders to minimum. Then on an axis by axis basis: First, increase responsiveness until the filter only just cancels jerkiness for faster head movements. Second, increase drift speed until the filter only just cancels drift movement when your head is still. + + + + + tomDll + + Tom + + + + diff --git a/filter-nm/lang/ru_RU.ts b/filter-nm/lang/ru_RU.ts new file mode 100644 index 000000000..b72d73ad6 --- /dev/null +++ b/filter-nm/lang/ru_RU.ts @@ -0,0 +1,78 @@ + + + + + UICdialog_tom + + Dialog + + + + X + + + + Y + + + + Z + + + + Yaw + + + + Pitch + + + + Roll + + + + °/s + + + + mm/s + + + + Responsiveness + + + + 10.0 + + + + Drift speeds + + + + 50 + + + + 100 + + + + Natural movement filter: cancels higher frequency noise and the natural tendency for our heads to drift even when we think we are sitting still. + + + + Instructions: Set all sliders to minimum. Then on an axis by axis basis: First, increase responsiveness until the filter only just cancels jerkiness for faster head movements. Second, increase drift speed until the filter only just cancels drift movement when your head is still. + + + + + tomDll + + Tom + + + + diff --git a/filter-nm/lang/stub.ts b/filter-nm/lang/stub.ts new file mode 100644 index 000000000..f212040f3 --- /dev/null +++ b/filter-nm/lang/stub.ts @@ -0,0 +1,78 @@ + + + + + UICdialog_tom + + Dialog + + + + X + + + + Y + + + + Z + + + + Yaw + + + + Pitch + + + + Roll + + + + °/s + + + + mm/s + + + + Responsiveness + + + + 10.0 + + + + Drift speeds + + + + 50 + + + + 100 + + + + Natural movement filter: cancels higher frequency noise and the natural tendency for our heads to drift even when we think we are sitting still. + + + + Instructions: Set all sliders to minimum. Then on an axis by axis basis: First, increase responsiveness until the filter only just cancels jerkiness for faster head movements. Second, increase drift speed until the filter only just cancels drift movement when your head is still. + + + + + tomDll + + Tom + + + + diff --git a/filter-nm/lang/zh_CN.ts b/filter-nm/lang/zh_CN.ts new file mode 100644 index 000000000..5a3229135 --- /dev/null +++ b/filter-nm/lang/zh_CN.ts @@ -0,0 +1,78 @@ + + + + + UICdialog_tom + + Dialog + + + + X + + + + Y + + + + Z + + + + Yaw + + + + Pitch + + + + Roll + + + + °/s + + + + mm/s + + + + Responsiveness + + + + 10.0 + + + + Drift speeds + + + + 50 + + + + 100 + + + + Natural movement filter: cancels higher frequency noise and the natural tendency for our heads to drift even when we think we are sitting still. + + + + Instructions: Set all sliders to minimum. Then on an axis by axis basis: First, increase responsiveness until the filter only just cancels jerkiness for faster head movements. Second, increase drift speed until the filter only just cancels drift movement when your head is still. + + + + + tomDll + + Tom + + + + -- cgit v1.2.3 From bd04206c6a86a46bceff710749ef4119303a1f85 Mon Sep 17 00:00:00 2001 From: Tom Brazier Date: Tue, 30 May 2023 16:34:37 +0100 Subject: Picked a name - natural movement filter --- filter-nm/CMakeLists.txt | 2 +- filter-nm/ftnoir_filter_nm.cpp | 8 ++++---- filter-nm/ftnoir_filter_nm.h | 26 +++++++++++++------------- filter-nm/ftnoir_filter_nm_dialog.cpp | 14 +++++++------- filter-nm/ftnoir_nm_filtercontrols.ui | 8 ++++---- filter-nm/lang/nl_NL.ts | 6 +++--- filter-nm/lang/ru_RU.ts | 6 +++--- filter-nm/lang/stub.ts | 6 +++--- filter-nm/lang/zh_CN.ts | 6 +++--- 9 files changed, 41 insertions(+), 41 deletions(-) (limited to 'filter-nm') diff --git a/filter-nm/CMakeLists.txt b/filter-nm/CMakeLists.txt index d98e90e21..49daaee2d 100644 --- a/filter-nm/CMakeLists.txt +++ b/filter-nm/CMakeLists.txt @@ -1 +1 @@ -otr_module(filter-tom) +otr_module(filter-nm) diff --git a/filter-nm/ftnoir_filter_nm.cpp b/filter-nm/ftnoir_filter_nm.cpp index 6bcfeae0f..b616f7229 100644 --- a/filter-nm/ftnoir_filter_nm.cpp +++ b/filter-nm/ftnoir_filter_nm.cpp @@ -4,7 +4,7 @@ * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. */ -#include "filter_tom.h" +#include "ftnoir_filter_nm.h" #include "compat/math-imports.hpp" #include "compat/macros.h" @@ -13,11 +13,11 @@ #include -tom::tom() +filter_nm::filter_nm() { } -void tom::filter(const double* input, double* output) +void filter_nm::filter(const double* input, double* output) { // order of axes: x, y, z, yaw, pitch, roll if (unlikely(first_run)) @@ -45,4 +45,4 @@ void tom::filter(const double* input, double* output) std::copy(filtered_output, filtered_output + 6, output); } -OPENTRACK_DECLARE_FILTER(tom, dialog_tom, tomDll) +OPENTRACK_DECLARE_FILTER(filter_nm, dialog_nm, nmDll) diff --git a/filter-nm/ftnoir_filter_nm.h b/filter-nm/ftnoir_filter_nm.h index 0f6d07c20..fe0924d10 100644 --- a/filter-nm/ftnoir_filter_nm.h +++ b/filter-nm/ftnoir_filter_nm.h @@ -6,7 +6,7 @@ */ #pragma once -#include "ui_tom_filtercontrols.h" +#include "ui_ftnoir_nm_filtercontrols.h" #include "api/plugin-api.hpp" #include "compat/timer.hpp" @@ -14,13 +14,13 @@ using namespace options; -struct settings_tom : opts +struct settings_nm : opts { value responsiveness[6]; value drift_speeds[6]; - settings_tom() : - opts("tom-filter"), + settings_nm() : + opts("nm-filter"), responsiveness{ value(b, "x-responsiveness", { 10.0, .0, 20.0 }), value(b, "y-responsiveness", { 10.0, .0, 20.0 }), value(b, "z-responsiveness", { 10.0, .0, 20.0 }), @@ -47,9 +47,9 @@ struct settings_tom : opts */ }; -struct tom : IFilter +struct filter_nm : IFilter { - tom(); + filter_nm(); void filter(const double* input, double* output) override; void center() override { first_run = true; } module_status initialize() override { return status_ok(); } @@ -59,15 +59,15 @@ private: double speeds[6]{}; double filtered_output[6]{}; Timer t; - settings_tom s; + settings_nm s; bool first_run = true; }; -class dialog_tom : public IFilterDialog +class dialog_nm : public IFilterDialog { Q_OBJECT public: - dialog_tom(); + dialog_nm(); void register_filter(IFilter*) override {} void unregister_filter() override {} void save() override; @@ -76,18 +76,18 @@ public: void set_buttons_visible(bool x) override; private: - Ui::UICdialog_tom ui; - settings_tom s; + Ui::UICdialog_nm ui; + settings_nm s; private slots: void doOK(); void doCancel(); }; -class tomDll : public Metadata +class nmDll : public Metadata { Q_OBJECT - QString name() override { return tr("Tom"); } + QString name() override { return tr("NaturalMovement"); } QIcon icon() override { return QIcon(":/images/filter-16.png"); } }; diff --git a/filter-nm/ftnoir_filter_nm_dialog.cpp b/filter-nm/ftnoir_filter_nm_dialog.cpp index 5a6ad3a42..ccf894db5 100644 --- a/filter-nm/ftnoir_filter_nm_dialog.cpp +++ b/filter-nm/ftnoir_filter_nm_dialog.cpp @@ -4,11 +4,11 @@ * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. */ -#include "filter_tom.h" +#include "ftnoir_filter_nm.h" using namespace options; -dialog_tom::dialog_tom() +dialog_nm::dialog_nm() { ui.setupUi(this); @@ -61,28 +61,28 @@ dialog_tom::dialog_tom() { return QStringLiteral("%1").arg(x, 0, 'f', 2); }); } -void dialog_tom::doOK() +void dialog_nm::doOK() { save(); close(); } -void dialog_tom::doCancel() +void dialog_nm::doCancel() { close(); } -void dialog_tom::save() +void dialog_nm::save() { s.b->save(); } -void dialog_tom::reload() +void dialog_nm::reload() { s.b->reload(); } -void dialog_tom::set_buttons_visible(bool x) +void dialog_nm::set_buttons_visible(bool x) { ui.buttonBox->setVisible(x); } diff --git a/filter-nm/ftnoir_nm_filtercontrols.ui b/filter-nm/ftnoir_nm_filtercontrols.ui index 1a135c1ed..c50cc1a6a 100644 --- a/filter-nm/ftnoir_nm_filtercontrols.ui +++ b/filter-nm/ftnoir_nm_filtercontrols.ui @@ -1,7 +1,7 @@ - UICdialog_tom - + UICdialog_nm + 0 @@ -577,7 +577,7 @@ buttonBox accepted() - UICdialog_tom + UICdialog_nm accept() @@ -593,7 +593,7 @@ buttonBox rejected() - UICdialog_tom + UICdialog_nm reject() diff --git a/filter-nm/lang/nl_NL.ts b/filter-nm/lang/nl_NL.ts index ce0aefe31..b3c85f917 100644 --- a/filter-nm/lang/nl_NL.ts +++ b/filter-nm/lang/nl_NL.ts @@ -2,7 +2,7 @@ - UICdialog_tom + UICdialog_nm Dialog @@ -69,9 +69,9 @@ - tomDll + nmDll - Tom + NaturalMovement diff --git a/filter-nm/lang/ru_RU.ts b/filter-nm/lang/ru_RU.ts index b72d73ad6..456ed403d 100644 --- a/filter-nm/lang/ru_RU.ts +++ b/filter-nm/lang/ru_RU.ts @@ -2,7 +2,7 @@ - UICdialog_tom + UICdialog_nm Dialog @@ -69,9 +69,9 @@ - tomDll + nmDll - Tom + NaturalMovement diff --git a/filter-nm/lang/stub.ts b/filter-nm/lang/stub.ts index f212040f3..875051cda 100644 --- a/filter-nm/lang/stub.ts +++ b/filter-nm/lang/stub.ts @@ -2,7 +2,7 @@ - UICdialog_tom + UICdialog_nm Dialog @@ -69,9 +69,9 @@ - tomDll + nmDll - Tom + NaturalMovement diff --git a/filter-nm/lang/zh_CN.ts b/filter-nm/lang/zh_CN.ts index 5a3229135..561030af5 100644 --- a/filter-nm/lang/zh_CN.ts +++ b/filter-nm/lang/zh_CN.ts @@ -2,7 +2,7 @@ - UICdialog_tom + UICdialog_nm Dialog @@ -69,9 +69,9 @@ - tomDll + nmDll - Tom + NaturalMovement -- cgit v1.2.3 From 1e88d84e1df7d04e0a17d70e07ecdc2586d8b5e6 Mon Sep 17 00:00:00 2001 From: Tom Brazier Date: Tue, 30 May 2023 16:56:06 +0100 Subject: dialog cleanup --- filter-nm/ftnoir_nm_filtercontrols.ui | 26 ++++++++++++++++++++------ filter-nm/lang/nl_NL.ts | 4 ++-- filter-nm/lang/ru_RU.ts | 4 ++-- filter-nm/lang/stub.ts | 4 ++-- filter-nm/lang/zh_CN.ts | 4 ++-- 5 files changed, 28 insertions(+), 14 deletions(-) (limited to 'filter-nm') diff --git a/filter-nm/ftnoir_nm_filtercontrols.ui b/filter-nm/ftnoir_nm_filtercontrols.ui index c50cc1a6a..93f3cb919 100644 --- a/filter-nm/ftnoir_nm_filtercontrols.ui +++ b/filter-nm/ftnoir_nm_filtercontrols.ui @@ -292,7 +292,7 @@ - 30 + 40 0 @@ -342,7 +342,7 @@ - 30 + 40 0 @@ -358,7 +358,7 @@ - 30 + 40 0 @@ -381,7 +381,7 @@ - 30 + 40 0 @@ -424,7 +424,7 @@ - 30 + 40 0 @@ -519,7 +519,7 @@ - 30 + 40 0 @@ -572,6 +572,20 @@ + + x_responsiveness_slider + y_responsiveness_slider + z_responsiveness_slider + yaw_responsiveness_slider + pitch_responsiveness_slider + roll_responsiveness_slider + x_drift_speed_slider + y_drift_speed_slider + z_drift_speed_slider + yaw_drift_speed_slider + pitch_drift_speed_slider + roll_drift_speed_slider + diff --git a/filter-nm/lang/nl_NL.ts b/filter-nm/lang/nl_NL.ts index b3c85f917..d68712e95 100644 --- a/filter-nm/lang/nl_NL.ts +++ b/filter-nm/lang/nl_NL.ts @@ -60,11 +60,11 @@ - Natural movement filter: cancels higher frequency noise and the natural tendency for our heads to drift even when we think we are sitting still. + Instructions: Set all sliders to minimum. Then on an axis by axis basis: First, increase responsiveness until the filter only just cancels jerkiness for faster head movements. Second, increase drift speed until the filter only just cancels drift movement when your head is still. - Instructions: Set all sliders to minimum. Then on an axis by axis basis: First, increase responsiveness until the filter only just cancels jerkiness for faster head movements. Second, increase drift speed until the filter only just cancels drift movement when your head is still. + Natural movement filter by Tom Brazier: Cancels higher frequency noise and the natural tendency for our heads to drift even when we think we are sitting still. diff --git a/filter-nm/lang/ru_RU.ts b/filter-nm/lang/ru_RU.ts index 456ed403d..9ea3d1587 100644 --- a/filter-nm/lang/ru_RU.ts +++ b/filter-nm/lang/ru_RU.ts @@ -60,11 +60,11 @@ - Natural movement filter: cancels higher frequency noise and the natural tendency for our heads to drift even when we think we are sitting still. + Instructions: Set all sliders to minimum. Then on an axis by axis basis: First, increase responsiveness until the filter only just cancels jerkiness for faster head movements. Second, increase drift speed until the filter only just cancels drift movement when your head is still. - Instructions: Set all sliders to minimum. Then on an axis by axis basis: First, increase responsiveness until the filter only just cancels jerkiness for faster head movements. Second, increase drift speed until the filter only just cancels drift movement when your head is still. + Natural movement filter by Tom Brazier: Cancels higher frequency noise and the natural tendency for our heads to drift even when we think we are sitting still. diff --git a/filter-nm/lang/stub.ts b/filter-nm/lang/stub.ts index 875051cda..61c1f5bcc 100644 --- a/filter-nm/lang/stub.ts +++ b/filter-nm/lang/stub.ts @@ -60,11 +60,11 @@ - Natural movement filter: cancels higher frequency noise and the natural tendency for our heads to drift even when we think we are sitting still. + Instructions: Set all sliders to minimum. Then on an axis by axis basis: First, increase responsiveness until the filter only just cancels jerkiness for faster head movements. Second, increase drift speed until the filter only just cancels drift movement when your head is still. - Instructions: Set all sliders to minimum. Then on an axis by axis basis: First, increase responsiveness until the filter only just cancels jerkiness for faster head movements. Second, increase drift speed until the filter only just cancels drift movement when your head is still. + Natural movement filter by Tom Brazier: Cancels higher frequency noise and the natural tendency for our heads to drift even when we think we are sitting still. diff --git a/filter-nm/lang/zh_CN.ts b/filter-nm/lang/zh_CN.ts index 561030af5..d6490d99e 100644 --- a/filter-nm/lang/zh_CN.ts +++ b/filter-nm/lang/zh_CN.ts @@ -60,11 +60,11 @@ - Natural movement filter: cancels higher frequency noise and the natural tendency for our heads to drift even when we think we are sitting still. + Instructions: Set all sliders to minimum. Then on an axis by axis basis: First, increase responsiveness until the filter only just cancels jerkiness for faster head movements. Second, increase drift speed until the filter only just cancels drift movement when your head is still. - Instructions: Set all sliders to minimum. Then on an axis by axis basis: First, increase responsiveness until the filter only just cancels jerkiness for faster head movements. Second, increase drift speed until the filter only just cancels drift movement when your head is still. + Natural movement filter by Tom Brazier: Cancels higher frequency noise and the natural tendency for our heads to drift even when we think we are sitting still. -- cgit v1.2.3 From 26db426f05657edcaf4bd5ea84d807e63c7ef181 Mon Sep 17 00:00:00 2001 From: Tom Brazier Date: Fri, 2 Jun 2023 15:25:04 +0100 Subject: corrected EWA logic for large values of dt * responsiveness --- filter-nm/ftnoir_filter_nm.cpp | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) (limited to 'filter-nm') diff --git a/filter-nm/ftnoir_filter_nm.cpp b/filter-nm/ftnoir_filter_nm.cpp index b616f7229..cd395f1bf 100644 --- a/filter-nm/ftnoir_filter_nm.cpp +++ b/filter-nm/ftnoir_filter_nm.cpp @@ -36,8 +36,10 @@ void filter_nm::filter(const double* input, double* output) for (int i = 0; i < 6; i++) { double speed = (input[i] - last_input[i]) / dt; - speeds[i] += dt * (double)s.responsiveness[i] * (speed - speeds[i]); - filtered_output[i] += dt * (double)s.responsiveness[i] * min(1.0, abs(speeds[i]) / (double)s.drift_speeds[i]) * (input[i] - filtered_output[i]); + double timescale = 1. / *(s.responsiveness[i]); + double alpha = dt / (dt + timescale); + speeds[i] += alpha * (speed - speeds[i]); // EWA + filtered_output[i] += alpha * min(1.0, abs(speeds[i]) / *(s.drift_speeds[i])) * (input[i] - filtered_output[i]); } } -- cgit v1.2.3 From 0962b47c9cd39a72160b3c0d96f21cd7eb907f26 Mon Sep 17 00:00:00 2001 From: Tom Brazier Date: Sat, 3 Jun 2023 21:15:39 +0100 Subject: Removed commented sample code --- filter-nm/ftnoir_filter_nm.h | 10 ---------- 1 file changed, 10 deletions(-) (limited to 'filter-nm') diff --git a/filter-nm/ftnoir_filter_nm.h b/filter-nm/ftnoir_filter_nm.h index fe0924d10..d2eae43d6 100644 --- a/filter-nm/ftnoir_filter_nm.h +++ b/filter-nm/ftnoir_filter_nm.h @@ -35,16 +35,6 @@ struct settings_nm : opts value(b, "roll-drift-speed", { 100.0, 1.0, 400.0 }) } { } - - /* value kMinSmoothing, kMaxSmoothing, kSmoothingScaleCurve; - settings() - : opts("ewma-filter"), - kMinSmoothing(b, "min-smoothing", { .02, .01, 1 }), - kMaxSmoothing(b, "max-smoothing", { .7, .01, 1 }), - kSmoothingScaleCurve(b, "smoothing-scale-curve", { .8, .1, 5 }) - { - } -*/ }; struct filter_nm : IFilter -- cgit v1.2.3 From 89c346c1b1a7d0d395d446a2113ff5e6771441fe Mon Sep 17 00:00:00 2001 From: Tom Brazier Date: Mon, 5 Jun 2023 15:53:14 +0100 Subject: Changed nm filter to use vectors and quaterions like the hamilton filter for a spherical deadzone --- filter-nm/ftnoir_filter_nm.cpp | 43 ++-- filter-nm/ftnoir_filter_nm.h | 32 ++- filter-nm/ftnoir_filter_nm_dialog.cpp | 48 +--- filter-nm/ftnoir_nm_filtercontrols.ui | 400 ++++------------------------------ filter-nm/lang/nl_NL.ts | 36 +-- filter-nm/lang/ru_RU.ts | 36 +-- filter-nm/lang/stub.ts | 36 +-- filter-nm/lang/zh_CN.ts | 36 +-- 8 files changed, 136 insertions(+), 531 deletions(-) (limited to 'filter-nm') diff --git a/filter-nm/ftnoir_filter_nm.cpp b/filter-nm/ftnoir_filter_nm.cpp index cd395f1bf..5d274790e 100644 --- a/filter-nm/ftnoir_filter_nm.cpp +++ b/filter-nm/ftnoir_filter_nm.cpp @@ -19,32 +19,47 @@ filter_nm::filter_nm() void filter_nm::filter(const double* input, double* output) { + tVector position = { input[TX], input[TY], input[TZ] }; + tQuat rotation = QuatFromYPR(input + Yaw); + // order of axes: x, y, z, yaw, pitch, roll if (unlikely(first_run)) { first_run = false; t.start(); - std::fill(speeds, speeds + 6, 0.0); - std::copy(input, input + 6, filtered_output); + last_pos_speed = tVector(); + last_rot_speed = tQuat(); + last_pos_out = position; + last_rot_out = rotation; } else { const double dt = t.elapsed_seconds(); t.start(); - for (int i = 0; i < 6; i++) - { - double speed = (input[i] - last_input[i]) / dt; - double timescale = 1. / *(s.responsiveness[i]); - double alpha = dt / (dt + timescale); - speeds[i] += alpha * (speed - speeds[i]); // EWA - filtered_output[i] += alpha * min(1.0, abs(speeds[i]) / *(s.drift_speeds[i])) * (input[i] - filtered_output[i]); - } - } - - std::copy(input, input + 6, last_input); - std::copy(filtered_output, filtered_output + 6, output); + const tVector pos_speed = (position - last_pos_in) / dt; + const double pos_tau = 1. / *s.pos_responsiveness; + double alpha = dt / (dt + pos_tau); + last_pos_speed += (pos_speed - last_pos_speed) * alpha; + alpha *= min(1.0, VectorLength(last_pos_speed) / *s.pos_drift_speed); + last_pos_out += (position - last_pos_out) * alpha; + + const tQuat rot_delta = QuatDivide(rotation, last_rot_in); + const double ms_per_s = 1000.0; // angular speed quaternions need to be small to work so use °/ms + const tQuat rot_speed = Slerp(tQuat(), rot_delta, 1.0 / dt / ms_per_s); + const double rot_tau = 1. / *s.rot_responsiveness; + alpha = dt / (dt + rot_tau); + last_rot_speed = Slerp(last_rot_speed, rot_speed, alpha); + const double angular_speed = AngleBetween(tQuat(), last_rot_speed) * ms_per_s; + alpha *= min(1.0, angular_speed / *s.rot_drift_speed); + last_rot_out = Slerp(last_rot_out, rotation, alpha); + } + + last_pos_in = position; + last_rot_in = rotation; + std::copy(last_pos_out.v, last_pos_out.v + 3, output + TX); + QuatToYPR(last_rot_out, &output[Yaw]); } OPENTRACK_DECLARE_FILTER(filter_nm, dialog_nm, nmDll) diff --git a/filter-nm/ftnoir_filter_nm.h b/filter-nm/ftnoir_filter_nm.h index d2eae43d6..7bf012a6b 100644 --- a/filter-nm/ftnoir_filter_nm.h +++ b/filter-nm/ftnoir_filter_nm.h @@ -10,29 +10,24 @@ #include "api/plugin-api.hpp" #include "compat/timer.hpp" +#include "compat/hamilton-tools.h" #include "options/options.hpp" using namespace options; struct settings_nm : opts { - value responsiveness[6]; - value drift_speeds[6]; + value pos_responsiveness; + value rot_responsiveness; + value pos_drift_speed; + value rot_drift_speed; settings_nm() : opts("nm-filter"), - responsiveness{ value(b, "x-responsiveness", { 10.0, .0, 20.0 }), - value(b, "y-responsiveness", { 10.0, .0, 20.0 }), - value(b, "z-responsiveness", { 10.0, .0, 20.0 }), - value(b, "yaw-responsiveness", { 10.0, .0, 20.0 }), - value(b, "pitch-responsiveness", { 10.0, .0, 20.0 }), - value(b, "roll-responsiveness", { 10.0, .0, 20.0 }) }, - drift_speeds{ value(b, "x-drift-speed", { 50.0, 1.0, 200.0 }), - value(b, "y-drift-speed", { 50.0, 1.0, 200.0 }), - value(b, "z-drift-speed", { 50.0, 1.0, 200.0 }), - value(b, "yaw-drift-speed", { 100.0, 1.0, 400.0 }), - value(b, "pitch-drift-speed", { 100.0, 1.0, 400.0 }), - value(b, "roll-drift-speed", { 100.0, 1.0, 400.0 }) } + pos_responsiveness(value(b, "pos-responsiveness", { 15.0, .0, 20.0 })), + rot_responsiveness(value(b, "rot-responsiveness", { 18.0, .0, 20.0 })), + pos_drift_speed(value(b, "pos-drift-speed", { 30.0, 1.0, 200.0 })), + rot_drift_speed(value(b, "rot-drift-speed", { 45.0, 1.0, 400.0 })) { } }; @@ -45,9 +40,12 @@ struct filter_nm : IFilter module_status initialize() override { return status_ok(); } private: - double last_input[6]{}; - double speeds[6]{}; - double filtered_output[6]{}; + tVector last_pos_in; + tQuat last_rot_in; + tVector last_pos_out; + tQuat last_rot_out; + tVector last_pos_speed; + tQuat last_rot_speed; Timer t; settings_nm s; bool first_run = true; diff --git a/filter-nm/ftnoir_filter_nm_dialog.cpp b/filter-nm/ftnoir_filter_nm_dialog.cpp index ccf894db5..f3626caeb 100644 --- a/filter-nm/ftnoir_filter_nm_dialog.cpp +++ b/filter-nm/ftnoir_filter_nm_dialog.cpp @@ -12,52 +12,20 @@ dialog_nm::dialog_nm() { ui.setupUi(this); - tie_setting(s.responsiveness[0], ui.x_responsiveness_slider); - tie_setting(s.responsiveness[0], ui.x_responsiveness, [](double x) + tie_setting(s.pos_responsiveness, ui.pos_responsiveness_slider); + tie_setting(s.pos_responsiveness, ui.pos_responsiveness, [](double x) { return QStringLiteral("%1").arg(x, 0, 'f', 2); }); - tie_setting(s.responsiveness[1], ui.y_responsiveness_slider); - tie_setting(s.responsiveness[1], ui.y_responsiveness, [](double x) + tie_setting(s.rot_responsiveness, ui.rot_responsiveness_slider); + tie_setting(s.rot_responsiveness, ui.rot_responsiveness, [](double x) { return QStringLiteral("%1").arg(x, 0, 'f', 2); }); - tie_setting(s.responsiveness[2], ui.z_responsiveness_slider); - tie_setting(s.responsiveness[2], ui.z_responsiveness, [](double x) + tie_setting(s.pos_drift_speed, ui.pos_drift_speed_slider); + tie_setting(s.pos_drift_speed, ui.pos_drift_speed, [](double x) { return QStringLiteral("%1").arg(x, 0, 'f', 2); }); - tie_setting(s.responsiveness[3], ui.yaw_responsiveness_slider); - tie_setting(s.responsiveness[3], ui.yaw_responsiveness, [](double x) - { return QStringLiteral("%1").arg(x, 0, 'f', 2); }); - - tie_setting(s.responsiveness[4], ui.pitch_responsiveness_slider); - tie_setting(s.responsiveness[4], ui.pitch_responsiveness, [](double x) - { return QStringLiteral("%1").arg(x, 0, 'f', 2); }); - - tie_setting(s.responsiveness[5], ui.roll_responsiveness_slider); - tie_setting(s.responsiveness[5], ui.roll_responsiveness, [](double x) - { return QStringLiteral("%1").arg(x, 0, 'f', 2); }); - - tie_setting(s.drift_speeds[0], ui.x_drift_speed_slider); - tie_setting(s.drift_speeds[0], ui.x_drift_speed, [](double x) - { return QStringLiteral("%1").arg(x, 0, 'f', 2); }); - - tie_setting(s.drift_speeds[1], ui.y_drift_speed_slider); - tie_setting(s.drift_speeds[1], ui.y_drift_speed, [](double x) - { return QStringLiteral("%1").arg(x, 0, 'f', 2); }); - - tie_setting(s.drift_speeds[2], ui.z_drift_speed_slider); - tie_setting(s.drift_speeds[2], ui.z_drift_speed, [](double x) - { return QStringLiteral("%1").arg(x, 0, 'f', 2); }); - - tie_setting(s.drift_speeds[3], ui.yaw_drift_speed_slider); - tie_setting(s.drift_speeds[3], ui.yaw_drift_speed, [](double x) - { return QStringLiteral("%1").arg(x, 0, 'f', 2); }); - - tie_setting(s.drift_speeds[4], ui.pitch_drift_speed_slider); - tie_setting(s.drift_speeds[4], ui.pitch_drift_speed, [](double x) - { return QStringLiteral("%1").arg(x, 0, 'f', 2); }); - - tie_setting(s.drift_speeds[5], ui.roll_drift_speed_slider); - tie_setting(s.drift_speeds[5], ui.roll_drift_speed, [](double x) + tie_setting(s.rot_drift_speed, ui.rot_drift_speed_slider); + tie_setting(s.rot_drift_speed, ui.rot_drift_speed, [](double x) { return QStringLiteral("%1").arg(x, 0, 'f', 2); }); } diff --git a/filter-nm/ftnoir_nm_filtercontrols.ui b/filter-nm/ftnoir_nm_filtercontrols.ui index 93f3cb919..ad307daf1 100644 --- a/filter-nm/ftnoir_nm_filtercontrols.ui +++ b/filter-nm/ftnoir_nm_filtercontrols.ui @@ -20,15 +20,15 @@ Responsiveness - - + + - X + Rotation - + 0 @@ -49,31 +49,8 @@ - - - - - 0 - 0 - - - - 40 - - - Qt::Horizontal - - - - - - - Y - - - - + 30 @@ -89,7 +66,7 @@ - + 40 @@ -98,97 +75,14 @@ - - - - Z - - - - - - - - 30 - 0 - - - - 10.0 - - - Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter - - - - - - - 40 - - - Qt::Horizontal - - - - - - - Yaw - - - - - - - - 30 - 0 - - - - 10.0 - - - Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter - - - - - - - 40 - - - Qt::Horizontal - - - - - - - Pitch - - - - - - - - 30 - 0 - - - - 10.0 - - - Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + + + 0 + 0 + - - - - 40 @@ -197,36 +91,10 @@ - - - - Roll - - - - - - - - 30 - 0 - - + + - 10.0 - - - Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter - - - - - - - 40 - - - Qt::Horizontal + Position @@ -261,85 +129,28 @@ Drift speeds - - - - Z - - - - - - - 1 - - - 200 - - - Qt::Horizontal - - - - - - - Roll - - - - - - - - 40 - 0 - - - - 50 - - - Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter - - - - - - - °/s - - - - - + + mm/s - - + + - °/s + Position - - - - 1 - - - 200 - - - Qt::Horizontal + + + + + 0 + 0 + - - - - 40 @@ -354,54 +165,8 @@ - - - - - 40 - 0 - - - - 100 - - - Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter - - - - - - - Y - - - - - - - - 40 - 0 - - - - 100 - - - Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter - - - - - - - Pitch - - - - - + + 1 @@ -413,15 +178,15 @@ - - + + - X + Rotation - - + + 40 @@ -436,29 +201,15 @@ - - - - mm/s - - - - - - - mm/s - - - - - + + - Yaw + °/s - + 0 @@ -476,61 +227,6 @@ - - - - °/s - - - - - - - 1 - - - 400 - - - Qt::Horizontal - - - - - - - 1 - - - 400 - - - Qt::Horizontal - - - - - - - - 0 - 0 - - - - - 40 - 0 - - - - 50 - - - Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter - - - @@ -547,7 +243,7 @@ - Instructions: Set all sliders to minimum. Then on an axis by axis basis: First, increase responsiveness until the filter only just cancels jerkiness for faster head movements. Second, increase drift speed until the filter only just cancels drift movement when your head is still. + Instructions: Set all sliders to minimum. Then for each of rotation and position: First, increase responsiveness until the filter only just cancels jerkiness for faster head movements. Second, increase drift speed until the filter only just cancels drift movement when your head is still. Qt::AlignLeading|Qt::AlignLeft|Qt::AlignTop @@ -573,18 +269,10 @@ - x_responsiveness_slider - y_responsiveness_slider - z_responsiveness_slider - yaw_responsiveness_slider - pitch_responsiveness_slider - roll_responsiveness_slider - x_drift_speed_slider - y_drift_speed_slider - z_drift_speed_slider - yaw_drift_speed_slider - pitch_drift_speed_slider - roll_drift_speed_slider + pos_responsiveness_slider + rot_responsiveness_slider + pos_drift_speed_slider + rot_drift_speed_slider diff --git a/filter-nm/lang/nl_NL.ts b/filter-nm/lang/nl_NL.ts index d68712e95..540e2d51b 100644 --- a/filter-nm/lang/nl_NL.ts +++ b/filter-nm/lang/nl_NL.ts @@ -7,30 +7,6 @@ Dialog - - X - - - - Y - - - - Z - - - - Yaw - - - - Pitch - - - - Roll - - °/s @@ -60,11 +36,19 @@ - Instructions: Set all sliders to minimum. Then on an axis by axis basis: First, increase responsiveness until the filter only just cancels jerkiness for faster head movements. Second, increase drift speed until the filter only just cancels drift movement when your head is still. + Natural movement filter by Tom Brazier: Cancels higher frequency noise and the natural tendency for our heads to drift even when we think we are sitting still. - Natural movement filter by Tom Brazier: Cancels higher frequency noise and the natural tendency for our heads to drift even when we think we are sitting still. + Rotation + + + + Position + + + + Instructions: Set all sliders to minimum. Then for each of rotation and position: First, increase responsiveness until the filter only just cancels jerkiness for faster head movements. Second, increase drift speed until the filter only just cancels drift movement when your head is still. diff --git a/filter-nm/lang/ru_RU.ts b/filter-nm/lang/ru_RU.ts index 9ea3d1587..31e5d5ccb 100644 --- a/filter-nm/lang/ru_RU.ts +++ b/filter-nm/lang/ru_RU.ts @@ -7,30 +7,6 @@ Dialog - - X - - - - Y - - - - Z - - - - Yaw - - - - Pitch - - - - Roll - - °/s @@ -60,11 +36,19 @@ - Instructions: Set all sliders to minimum. Then on an axis by axis basis: First, increase responsiveness until the filter only just cancels jerkiness for faster head movements. Second, increase drift speed until the filter only just cancels drift movement when your head is still. + Natural movement filter by Tom Brazier: Cancels higher frequency noise and the natural tendency for our heads to drift even when we think we are sitting still. - Natural movement filter by Tom Brazier: Cancels higher frequency noise and the natural tendency for our heads to drift even when we think we are sitting still. + Rotation + + + + Position + + + + Instructions: Set all sliders to minimum. Then for each of rotation and position: First, increase responsiveness until the filter only just cancels jerkiness for faster head movements. Second, increase drift speed until the filter only just cancels drift movement when your head is still. diff --git a/filter-nm/lang/stub.ts b/filter-nm/lang/stub.ts index 61c1f5bcc..3b9608046 100644 --- a/filter-nm/lang/stub.ts +++ b/filter-nm/lang/stub.ts @@ -7,30 +7,6 @@ Dialog - - X - - - - Y - - - - Z - - - - Yaw - - - - Pitch - - - - Roll - - °/s @@ -60,11 +36,19 @@ - Instructions: Set all sliders to minimum. Then on an axis by axis basis: First, increase responsiveness until the filter only just cancels jerkiness for faster head movements. Second, increase drift speed until the filter only just cancels drift movement when your head is still. + Natural movement filter by Tom Brazier: Cancels higher frequency noise and the natural tendency for our heads to drift even when we think we are sitting still. - Natural movement filter by Tom Brazier: Cancels higher frequency noise and the natural tendency for our heads to drift even when we think we are sitting still. + Rotation + + + + Position + + + + Instructions: Set all sliders to minimum. Then for each of rotation and position: First, increase responsiveness until the filter only just cancels jerkiness for faster head movements. Second, increase drift speed until the filter only just cancels drift movement when your head is still. diff --git a/filter-nm/lang/zh_CN.ts b/filter-nm/lang/zh_CN.ts index d6490d99e..92521e0fe 100644 --- a/filter-nm/lang/zh_CN.ts +++ b/filter-nm/lang/zh_CN.ts @@ -7,30 +7,6 @@ Dialog - - X - - - - Y - - - - Z - - - - Yaw - - - - Pitch - - - - Roll - - °/s @@ -60,11 +36,19 @@ - Instructions: Set all sliders to minimum. Then on an axis by axis basis: First, increase responsiveness until the filter only just cancels jerkiness for faster head movements. Second, increase drift speed until the filter only just cancels drift movement when your head is still. + Natural movement filter by Tom Brazier: Cancels higher frequency noise and the natural tendency for our heads to drift even when we think we are sitting still. - Natural movement filter by Tom Brazier: Cancels higher frequency noise and the natural tendency for our heads to drift even when we think we are sitting still. + Rotation + + + + Position + + + + Instructions: Set all sliders to minimum. Then for each of rotation and position: First, increase responsiveness until the filter only just cancels jerkiness for faster head movements. Second, increase drift speed until the filter only just cancels drift movement when your head is still. -- cgit v1.2.3 From fa839e3fc9b92a4642d50c28bc607eb97e9ac1df Mon Sep 17 00:00:00 2001 From: Tom Brazier Date: Sat, 10 Jun 2023 16:59:18 +0100 Subject: Change to a quadratic curve for alpha and use a scale where 3 * drift speed results in alpha == 1.0 --- filter-nm/ftnoir_filter_nm.cpp | 10 ++++++---- filter-nm/ftnoir_filter_nm.h | 8 ++++---- filter-nm/ftnoir_nm_filtercontrols.ui | 4 ++-- 3 files changed, 12 insertions(+), 10 deletions(-) (limited to 'filter-nm') diff --git a/filter-nm/ftnoir_filter_nm.cpp b/filter-nm/ftnoir_filter_nm.cpp index 5d274790e..b222184b7 100644 --- a/filter-nm/ftnoir_filter_nm.cpp +++ b/filter-nm/ftnoir_filter_nm.cpp @@ -42,17 +42,19 @@ void filter_nm::filter(const double* input, double* output) const double pos_tau = 1. / *s.pos_responsiveness; double alpha = dt / (dt + pos_tau); last_pos_speed += (pos_speed - last_pos_speed) * alpha; - alpha *= min(1.0, VectorLength(last_pos_speed) / *s.pos_drift_speed); + const double factor_pos = min(1.0, VectorLength(last_pos_speed) / (*s.pos_drift_speed * 3.0)); + alpha *= factor_pos * factor_pos; last_pos_out += (position - last_pos_out) * alpha; const tQuat rot_delta = QuatDivide(rotation, last_rot_in); - const double ms_per_s = 1000.0; // angular speed quaternions need to be small to work so use °/ms - const tQuat rot_speed = Slerp(tQuat(), rot_delta, 1.0 / dt / ms_per_s); + constexpr double ms_per_s = 1000.0; // angular speed quaternions need to be small to work so use °/ms + const tQuat rot_speed = Slerp(tQuat(), rot_delta, 1.0 / ms_per_s / dt ); const double rot_tau = 1. / *s.rot_responsiveness; alpha = dt / (dt + rot_tau); last_rot_speed = Slerp(last_rot_speed, rot_speed, alpha); const double angular_speed = AngleBetween(tQuat(), last_rot_speed) * ms_per_s; - alpha *= min(1.0, angular_speed / *s.rot_drift_speed); + const double factor_rot = min(1.0, angular_speed / (*s.rot_drift_speed * 3.0)); + alpha *= factor_rot * factor_rot; last_rot_out = Slerp(last_rot_out, rotation, alpha); } diff --git a/filter-nm/ftnoir_filter_nm.h b/filter-nm/ftnoir_filter_nm.h index 7bf012a6b..84775207c 100644 --- a/filter-nm/ftnoir_filter_nm.h +++ b/filter-nm/ftnoir_filter_nm.h @@ -24,10 +24,10 @@ struct settings_nm : opts settings_nm() : opts("nm-filter"), - pos_responsiveness(value(b, "pos-responsiveness", { 15.0, .0, 20.0 })), - rot_responsiveness(value(b, "rot-responsiveness", { 18.0, .0, 20.0 })), - pos_drift_speed(value(b, "pos-drift-speed", { 30.0, 1.0, 200.0 })), - rot_drift_speed(value(b, "rot-drift-speed", { 45.0, 1.0, 400.0 })) + pos_responsiveness(value(b, "pos-responsiveness", { 13.0, .0, 20.0 })), + rot_responsiveness(value(b, "rot-responsiveness", { 16.0, .0, 20.0 })), + pos_drift_speed(value(b, "pos-drift-speed", { 5.0, 0.1, 50.0 })), + rot_drift_speed(value(b, "rot-drift-speed", { 7.0, 0.1, 50.0 })) { } }; diff --git a/filter-nm/ftnoir_nm_filtercontrols.ui b/filter-nm/ftnoir_nm_filtercontrols.ui index ad307daf1..7e317e740 100644 --- a/filter-nm/ftnoir_nm_filtercontrols.ui +++ b/filter-nm/ftnoir_nm_filtercontrols.ui @@ -171,7 +171,7 @@ 1 - 400 + 500 Qt::Horizontal @@ -220,7 +220,7 @@ 1 - 200 + 500 Qt::Horizontal -- cgit v1.2.3