From 9f4bc14bf6d5fbe4534953945a587c89a86a29f5 Mon Sep 17 00:00:00 2001 From: Michael Welter Date: Tue, 14 May 2024 19:50:04 +0200 Subject: Add new filter: HamiltonAccela which is a combination of ideas from Accela and Hamilton filters (#1843) --- filter-accela-hamilton/CMakeLists.txt | 2 + filter-accela-hamilton/accela_hamilton.cpp | 120 +++++ filter-accela-hamilton/accela_hamilton.h | 69 +++ filter-accela-hamilton/accela_hamilton_dialog.cpp | 99 +++++ .../accela_hamilton_filtercontrols.ui | 485 +++++++++++++++++++++ .../accela_hamilton_settings.hpp | 63 +++ filter-accela-hamilton/lang/nl_NL.ts | 82 ++++ filter-accela-hamilton/lang/ru_RU.ts | 82 ++++ filter-accela-hamilton/lang/stub.ts | 82 ++++ filter-accela-hamilton/lang/zh_CN.ts | 82 ++++ 10 files changed, 1166 insertions(+) create mode 100644 filter-accela-hamilton/CMakeLists.txt create mode 100644 filter-accela-hamilton/accela_hamilton.cpp create mode 100644 filter-accela-hamilton/accela_hamilton.h create mode 100644 filter-accela-hamilton/accela_hamilton_dialog.cpp create mode 100644 filter-accela-hamilton/accela_hamilton_filtercontrols.ui create mode 100644 filter-accela-hamilton/accela_hamilton_settings.hpp create mode 100644 filter-accela-hamilton/lang/nl_NL.ts create mode 100644 filter-accela-hamilton/lang/ru_RU.ts create mode 100644 filter-accela-hamilton/lang/stub.ts create mode 100644 filter-accela-hamilton/lang/zh_CN.ts diff --git a/filter-accela-hamilton/CMakeLists.txt b/filter-accela-hamilton/CMakeLists.txt new file mode 100644 index 00000000..825cef5e --- /dev/null +++ b/filter-accela-hamilton/CMakeLists.txt @@ -0,0 +1,2 @@ +otr_module(filter-accela-hamilton) +target_link_libraries(opentrack-filter-accela-hamilton opentrack-spline) diff --git a/filter-accela-hamilton/accela_hamilton.cpp b/filter-accela-hamilton/accela_hamilton.cpp new file mode 100644 index 00000000..5e7660a8 --- /dev/null +++ b/filter-accela-hamilton/accela_hamilton.cpp @@ -0,0 +1,120 @@ +/* Copyright (c) 2012-2015 Stanislaw Halik + * Copyright (c) 2023-2024 Michael Welter + * + * 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 "accela_hamilton.h" +#include "compat/math.hpp" +#include "api/plugin-api.hpp" +#include "opentrack/defs.hpp" + +#include +#include +#include + +#include "compat/math-imports.hpp" +#include "compat/time.hpp" + + +accela_hamilton::accela_hamilton() +{ + s.make_splines(spline_rot, spline_pos); +} + + +void accela_hamilton::filter(const double* input, double *output) +{ + constexpr float EPSILON = 1e-15F; + + const QQuaternion current_rot = QQuaternion::fromEulerAngles(input[Pitch], input[Yaw], input[Roll]); + const QVector3D current_pos(input[TX], input[TY], input[TZ]); + + if (unlikely(first_run)) + { + first_run = false; + last_rotation = current_rot; + last_position = current_pos; + t.start(); +#if defined DEBUG_ACCELA + debug_max = 0; + debug_timer.start(); +#endif + return; + } + + const float pos_thres{s.pos_smoothing}; + const float pos_dz{ s.pos_deadzone}; + + const float dt = t.elapsed_seconds(); + t.start(); + + // Position + { + const QVector3D delta = current_pos - last_position; + const float delta_len = delta.length(); + QVector3D delta_normed = delta_len>0.F ? delta/delta_len : QVector3D(); // Zero vector when length was zero. + const float gain = dt*spline_pos.get_value_no_save(std::max(0.F, delta_len-pos_dz) / pos_thres); + const QVector3D output_pos = last_position + gain * delta_normed; + output[TX] = output_pos.x(); + output[TY] = output_pos.y(); + output[TZ] = output_pos.z(); + last_position = output_pos; + } + + // Zoom smoothing: + const float zoomed_smoothing = [this](float output_z) { + // Local copies because accessing settings involves thread synchronization + // and I don't like this in the middle of math. + const float max_zoomed_smoothing {s.max_zoomed_smoothing}; + const float max_z {s.max_z}; + // Movement toward the monitor is negative. Negate and clamp it to get a positive value + const float z = std::clamp(-output_z, 0.F, max_z); + return max_zoomed_smoothing * z / (max_z + EPSILON); + }(output[TZ]); + + const float rot_dz{ s.rot_deadzone}; + const float rot_thres = float{s.rot_smoothing} + zoomed_smoothing; + + // Rotation + { + // Inter/extrapolates along the arc between the old and new orientation. + // It's basically a quaternion spherical linear interpolation, where the + // accela gain x dt is the blending parameter. Might actually overshoot + // the new orientation, but that's fine. + + // Compute rotation angle and axis which brings the previous orientation to the current rotation + QVector3D axis; + float angle; + (last_rotation.conjugated() * current_rot).getAxisAndAngle(&axis, &angle); + // Apply the Accela gain magic. Also need to multiply with dt here. + angle = std::max(0.f, angle - std::copysign(rot_dz, angle)) / rot_thres; + const float gain_angle = dt*spline_rot.get_value_no_save(std::abs(angle)) * signum(angle); + // Rotate toward the measured orientation. We take the already computed axis. But the angle is now the accela gain. + const QQuaternion output_rot = last_rotation * QQuaternion::fromAxisAndAngle(axis, gain_angle); + // And back to Euler angles + const QVector3D output_euler = output_rot.toEulerAngles(); + output[Pitch] = output_euler.x(); + output[Yaw] = output_euler.y(); + output[Roll] = output_euler.z(); + last_rotation = output_rot; + } +} + +namespace detail::accela_hamilton { + +void settings_accela_hamilton::make_splines(spline& rot, spline& pos) +{ + rot.clear(); pos.clear(); + + for (const auto& val : rot_gains) + rot.add_point({ val.x, val.y }); + + for (const auto& val : pos_gains) + pos.add_point({ val.x, val.y }); +} + +} // ns detail::accela_hamilton + +OPENTRACK_DECLARE_FILTER(accela_hamilton, dialog_accela_hamilton, accela_hamiltonDll) diff --git a/filter-accela-hamilton/accela_hamilton.h b/filter-accela-hamilton/accela_hamilton.h new file mode 100644 index 00000000..ccd74fbf --- /dev/null +++ b/filter-accela-hamilton/accela_hamilton.h @@ -0,0 +1,69 @@ +/* Copyright (c) 2012-2015 Stanislaw Halik + * Copyright (c) 2023-2024 Michael Welter + * + * 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_accela_hamilton_filtercontrols.h" + +#include "accela_hamilton_settings.hpp" +#include "api/plugin-api.hpp" +#include "compat/timer.hpp" +#include "compat/variance.hpp" + +#include +#include +#include +#include + +//#define DEBUG_ACCELA + +struct accela_hamilton : IFilter +{ + accela_hamilton(); + void filter(const double* input, double *output) override; + void center() override { first_run = true; } + spline spline_rot, spline_pos; + module_status initialize() override { return status_ok(); } +private: + settings_accela_hamilton s; + QVector3D last_position = {}; + QQuaternion last_rotation = {}; + Timer t; +#if defined DEBUG_ACCELA + Timer debug_timer; + double debug_max; + variance var; +#endif + bool first_run = true; +}; + +class dialog_accela_hamilton : public IFilterDialog +{ + Q_OBJECT +public: + dialog_accela_hamilton(); + 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::AccelaUICdialog_accela ui; + settings_accela_hamilton s; +private slots: + void doOK(); + void doCancel(); +}; + +class accela_hamiltonDll : public Metadata +{ + Q_OBJECT + + QString name() override { return tr("AccelaHamilton"); } + QIcon icon() override { return QIcon(":/images/filter-16.png"); } +}; diff --git a/filter-accela-hamilton/accela_hamilton_dialog.cpp b/filter-accela-hamilton/accela_hamilton_dialog.cpp new file mode 100644 index 00000000..711535f8 --- /dev/null +++ b/filter-accela-hamilton/accela_hamilton_dialog.cpp @@ -0,0 +1,99 @@ +/* Copyright (c) 2012-2015 Stanislaw Halik + * Copyright (c) 2023-2024 Michael Welter + * + * 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 "accela_hamilton.h" +#include +#include +#include +#include +#include "api/plugin-api.hpp" +#include "spline/spline-widget.hpp" +#include + +using namespace options; + +dialog_accela_hamilton::dialog_accela_hamilton() +{ + ui.setupUi(this); + + connect(ui.buttonBox, SIGNAL(accepted()), this, SLOT(doOK())); + connect(ui.buttonBox, SIGNAL(rejected()), this, SLOT(doCancel())); + + tie_setting(s.rot_smoothing, ui.rotation_slider); + tie_setting(s.pos_smoothing, ui.translation_slider); + tie_setting(s.rot_deadzone, ui.rot_dz_slider); + tie_setting(s.pos_deadzone, ui.trans_dz_slider); + + tie_setting(s.rot_smoothing, ui.rot_gain, [](const slider_value& s) { return tr("%1°").arg(s, 0, 'g', 4); }); + tie_setting(s.pos_smoothing, ui.trans_gain, [](const slider_value& s) { return tr("%1mm").arg(s, 0, 'g', 4); }); + tie_setting(s.rot_deadzone, ui.rot_dz, [](const slider_value& s) { return tr("%1°").arg(s, 0, 'g', 4); }); + tie_setting(s.pos_deadzone, ui.trans_dz, [](const slider_value& s) { return tr("%1mm").arg(s); }); + + tie_setting(s.max_zoomed_smoothing, ui.max_zoomed_smoothing); + tie_setting(s.max_zoomed_smoothing, ui.lb_max_zoomed_smoothing, [](double x) + { return tr("%1°").arg(x, 0, 'g', 3);}); + + tie_setting(s.max_z, ui.max_z); + tie_setting(s.max_z, ui.lb_max_z, [](double x) + { return tr("%1mm").arg(x, 0, 'g', 3);}); + +//#define SPLINE_ROT_DEBUG +//#define SPLINE_TRANS_DEBUG + +#if defined SPLINE_ROT_DEBUG || defined SPLINE_TRANS_DEBUG + { + spline rot, pos; + s.make_splines(rot, pos); + +#ifdef SPLINE_ROT_DEBUG + QDialog dr; + spline_widget r(&dr); + dr.setWindowTitle("Accela rotation gain"); r.set_preview_only(true); r.setEnabled(true); + r.setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed); r.set_config(&rot); + r.setFixedSize(1024, 600); + dr.show(); + dr.exec(); +#endif + +#ifdef SPLINE_TRANS_DEBUG + QDialog dt; + spline_widget t(&dt); + dt.setWindowTitle("Accela translation gain"); t.set_preview_only(true); t.setEnabled(true); + dt.setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed); t.set_config(&pos); + t.setFixedSize(1024, 600); + dt.show(); + dt.exec(); +#endif + } +#endif +} + +void dialog_accela_hamilton::doOK() +{ + save(); + close(); +} + +void dialog_accela_hamilton::doCancel() +{ + close(); +} + +void dialog_accela_hamilton::save() +{ + s.b->save(); +} + +void dialog_accela_hamilton::reload() +{ + s.b->reload(); +} + +void dialog_accela_hamilton::set_buttons_visible(bool x) +{ + ui.buttonBox->setVisible(x); +} diff --git a/filter-accela-hamilton/accela_hamilton_filtercontrols.ui b/filter-accela-hamilton/accela_hamilton_filtercontrols.ui new file mode 100644 index 00000000..f6049444 --- /dev/null +++ b/filter-accela-hamilton/accela_hamilton_filtercontrols.ui @@ -0,0 +1,485 @@ + + + AccelaUICdialog_accela + + + Qt::NonModal + + + + 0 + 0 + 632 + 628 + + + + + 0 + 0 + + + + + 550 + 0 + + + + Filter settings + + + + :/images/filter-16.png:/images/filter-16.png + + + + 5 + + + + + + 0 + 0 + + + + + 0 + 130 + + + + false + + + QFrame::NoFrame + + + QFrame::Plain + + + Qt::ScrollBarAlwaysOff + + + Qt::ScrollBarAlwaysOff + + + QAbstractScrollArea::AdjustToContents + + + <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> +<html><head><meta name="qrichtext" content="1" /><style type="text/css"> +p, li { white-space: pre-wrap; } +</style></head><body style=" font-family:'Ubuntu'; font-size:10pt; font-weight:400; font-style:normal;"> +<p align="center" style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-weight:600;">Accela + Hamilton Filter</span></p> +<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-weight:600;"><br /></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">For both rotations and positions: No movement occurs within the dead zone.</p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">For larger movements, rotation and translation occurs toward the new measurement. The strength is determined by the Smoothing setting and the builtin Accela gain curves.</p> +<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><br /></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">When you lean forward, smoothing is added up to the set maximum at the distance of Max Z.</p></body></html> + + + + + + + Rotation Smoothing (Added when zoomed) + + + + 4 + + + 4 + + + 9 + + + 2 + + + + + + 0 + 0 + + + + 0 + + + 25 + + + 1 + + + Qt::Horizontal + + + + + + + + 0 + 0 + + + + Max Added + + + + + + + + 0 + 0 + + + + 0 + + + 49 + + + 1 + + + Qt::Horizontal + + + QSlider::TicksAbove + + + 40 + + + + + + + + 50 + 0 + + + + + + + + + + + + 50 + 0 + + + + 0mm + + + + + + + Max Z + + + + + + + + + + + 0 + 0 + + + + QDialogButtonBox::Cancel|QDialogButtonBox::Ok + + + + + + + Position filtering (X, Y, Z - translation) + + + + 4 + + + 4 + + + 9 + + + 2 + + + + + + 0 + 0 + + + + 0 + + + 20 + + + 1 + + + Qt::Horizontal + + + + + + + + 0 + 0 + + + + Smoothing + + + + + + + + 0 + 0 + + + + 0 + + + 29 + + + 1 + + + Qt::Horizontal + + + QSlider::TicksAbove + + + 40 + + + + + + + + 50 + 0 + + + + 0mm + + + + + + + + 50 + 0 + + + + 0mm + + + + + + + Deadzone + + + + + trans_dz_slider + translation_slider + trans_dz + label_6 + trans_gain + label + + + + + + Rotation filtering (Yaw, pitch, and roll) + + + + 4 + + + 4 + + + 9 + + + 2 + + + + + + 0 + 0 + + + + Smoothing + + + + + + + + 50 + 0 + + + + + + + + + + + + 0 + 0 + + + + 0 + + + 49 + + + 1 + + + Qt::Horizontal + + + QSlider::TicksAbove + + + 50 + + + + + + + Deadzone + + + + + + + + 50 + 0 + + + + + + + + + + + + 0 + 0 + + + + 0 + + + 20 + + + 1 + + + Qt::Horizontal + + + + + + + + + + Qt::Vertical + + + + 20 + 40 + + + + + + + + rotation_slider + rot_dz_slider + translation_slider + trans_dz_slider + + + + + + + startEngineClicked() + stopEngineClicked() + cameraSettingsClicked() + + diff --git a/filter-accela-hamilton/accela_hamilton_settings.hpp b/filter-accela-hamilton/accela_hamilton_settings.hpp new file mode 100644 index 00000000..71ddf479 --- /dev/null +++ b/filter-accela-hamilton/accela_hamilton_settings.hpp @@ -0,0 +1,63 @@ +#pragma once + +#include "spline/spline.hpp" +#include "options/options.hpp" + +namespace detail::accela_hamilton { + +using namespace options; + +// ------------------------------------ +// debug knobs +// ------------------------------------ + +//#define DEBUG_ACCELA +//#define SPLINE_ROT_DEBUG +//#define SPLINE_TRANS_DEBUG + +struct settings_accela_hamilton : opts +{ + struct gains + { + double x, y; + }; + + static constexpr gains const rot_gains[] { + { 9, 300 }, + { 8, 200 }, + { 5, 100 }, + { 2.5, 35 }, + { 1.5, 8 }, + { 1, 1.5 }, + { .5, .4 }, + }; + + static constexpr gains const pos_gains[] { + { 9, 200 }, + { 8, 150 }, + { 7, 110 }, + { 5, 60 }, + { 3, 24 }, + { 2, 7.5 }, + { 1.66, 4.5 }, + { 1.33, 2.25 }, + { .66, .75 }, + { .33, .375 }, + { 0, 0 }, + }; + + static void make_splines(spline& rot, spline& pos); + + value rot_smoothing { b, "rotation-sensitivity", { 1.5, .05, 2.5 } }, + pos_smoothing { b, "translation-sensitivity", { 1., .05, 1.5 } }, + rot_deadzone { b, "rotation-deadzone", { .03, 0, .2 } }, + pos_deadzone { b, "translation-deadzone", { .1, 0, 1 } }, + max_zoomed_smoothing { b, "max_zoomed_smoothing", { .0, .0, 10. } }, + max_z { b, "max-z", { 10., .0, 30. } }; + + settings_accela_hamilton() : opts("accela-hamilton-sliders") {} +}; + +} // ns detail::accela_hamilton + +using detail::accela_hamilton::settings_accela_hamilton; diff --git a/filter-accela-hamilton/lang/nl_NL.ts b/filter-accela-hamilton/lang/nl_NL.ts new file mode 100644 index 00000000..13315922 --- /dev/null +++ b/filter-accela-hamilton/lang/nl_NL.ts @@ -0,0 +1,82 @@ + + + + + AccelaUICdialog_accela + + Filter settings + Filter-instellingen + + + Smoothing + Verzachten + + + Position filtering (X, Y, Z - translation) + + + + 0mm + 0mm + + + Deadzone + Deadzone + + + Rotation filtering (Yaw, pitch, and roll) + + + + 0° + + + + Rotation Smoothing (Added when zoomed) + + + + 0° + + + + Max Z + + + + Max Added + + + + <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> +<html><head><meta name="qrichtext" content="1" /><style type="text/css"> +p, li { white-space: pre-wrap; } +</style></head><body style=" font-family:'Ubuntu'; font-size:10pt; font-weight:400; font-style:normal;"> +<p align="center" style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-weight:600;">Accela + Hamilton Filter</span></p> +<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-weight:600;"><br /></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">For both rotations and positions: No movement occurs within the dead zone.</p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">For larger movements, rotation and translation occurs toward the new measurement. The strength is determined by the Smoothing setting and the builtin Accela gain curves.</p> +<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><br /></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">When you lean forward, smoothing is added up to the set maximum at the distance of Max Z.</p></body></html> + + + + + accela_hamiltonDll + + AccelaHamilton + + + + + dialog_accela_hamilton + + %1° + + + + %1mm + + + + diff --git a/filter-accela-hamilton/lang/ru_RU.ts b/filter-accela-hamilton/lang/ru_RU.ts new file mode 100644 index 00000000..7dd3e1eb --- /dev/null +++ b/filter-accela-hamilton/lang/ru_RU.ts @@ -0,0 +1,82 @@ + + + + + AccelaUICdialog_accela + + Filter settings + Настройка фильтра + + + Smoothing + Сглаживание + + + Position filtering (X, Y, Z - translation) + Фильтрация смещений (X, Y, Z) + + + 0mm + 0мм + + + Deadzone + Мертвая зона + + + Rotation filtering (Yaw, pitch, and roll) + Фильтрация поворотов (Рысканье, тангаж, крен) + + + 0° + + + + Rotation Smoothing (Added when zoomed) + + + + 0° + + + + Max Z + + + + Max Added + + + + <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> +<html><head><meta name="qrichtext" content="1" /><style type="text/css"> +p, li { white-space: pre-wrap; } +</style></head><body style=" font-family:'Ubuntu'; font-size:10pt; font-weight:400; font-style:normal;"> +<p align="center" style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-weight:600;">Accela + Hamilton Filter</span></p> +<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-weight:600;"><br /></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">For both rotations and positions: No movement occurs within the dead zone.</p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">For larger movements, rotation and translation occurs toward the new measurement. The strength is determined by the Smoothing setting and the builtin Accela gain curves.</p> +<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><br /></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">When you lean forward, smoothing is added up to the set maximum at the distance of Max Z.</p></body></html> + + + + + accela_hamiltonDll + + AccelaHamilton + + + + + dialog_accela_hamilton + + %1° + + + + %1mm + + + + diff --git a/filter-accela-hamilton/lang/stub.ts b/filter-accela-hamilton/lang/stub.ts new file mode 100644 index 00000000..2cd62df5 --- /dev/null +++ b/filter-accela-hamilton/lang/stub.ts @@ -0,0 +1,82 @@ + + + + + AccelaUICdialog_accela + + Filter settings + + + + Smoothing + + + + Position filtering (X, Y, Z - translation) + + + + 0mm + + + + Deadzone + + + + Rotation filtering (Yaw, pitch, and roll) + + + + 0° + + + + Rotation Smoothing (Added when zoomed) + + + + 0° + + + + Max Z + + + + Max Added + + + + <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> +<html><head><meta name="qrichtext" content="1" /><style type="text/css"> +p, li { white-space: pre-wrap; } +</style></head><body style=" font-family:'Ubuntu'; font-size:10pt; font-weight:400; font-style:normal;"> +<p align="center" style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-weight:600;">Accela + Hamilton Filter</span></p> +<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-weight:600;"><br /></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">For both rotations and positions: No movement occurs within the dead zone.</p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">For larger movements, rotation and translation occurs toward the new measurement. The strength is determined by the Smoothing setting and the builtin Accela gain curves.</p> +<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><br /></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">When you lean forward, smoothing is added up to the set maximum at the distance of Max Z.</p></body></html> + + + + + accela_hamiltonDll + + AccelaHamilton + + + + + dialog_accela_hamilton + + %1° + + + + %1mm + + + + diff --git a/filter-accela-hamilton/lang/zh_CN.ts b/filter-accela-hamilton/lang/zh_CN.ts new file mode 100644 index 00000000..43a12f5a --- /dev/null +++ b/filter-accela-hamilton/lang/zh_CN.ts @@ -0,0 +1,82 @@ + + + + + AccelaUICdialog_accela + + Filter settings + 过滤器设置 + + + Rotation filtering (Yaw, pitch, and roll) + 旋转过滤器 (偏航, 俯仰, 滚转) + + + Smoothing + 平滑 + + + 0° + + + + Deadzone + 死区 + + + Position filtering (X, Y, Z - translation) + 方位过滤器 (X, Y, Z - 变换) + + + 0mm + + + + Rotation Smoothing (Added when zoomed) + + + + 0° + + + + Max Z + + + + Max Added + + + + <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> +<html><head><meta name="qrichtext" content="1" /><style type="text/css"> +p, li { white-space: pre-wrap; } +</style></head><body style=" font-family:'Ubuntu'; font-size:10pt; font-weight:400; font-style:normal;"> +<p align="center" style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-weight:600;">Accela + Hamilton Filter</span></p> +<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-weight:600;"><br /></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">For both rotations and positions: No movement occurs within the dead zone.</p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">For larger movements, rotation and translation occurs toward the new measurement. The strength is determined by the Smoothing setting and the builtin Accela gain curves.</p> +<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><br /></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">When you lean forward, smoothing is added up to the set maximum at the distance of Max Z.</p></body></html> + + + + + accela_hamiltonDll + + AccelaHamilton + + + + + dialog_accela_hamilton + + %1° + + + + %1mm + + + + -- cgit v1.2.3