From 39c6a97a60415dd2b2634fa9e67f89b8766d313c Mon Sep 17 00:00:00 2001 From: Kostis Anagnostopoulos Date: Sun, 10 Mar 2024 22:11:47 +0200 Subject: [PATCH 01/11] doc(maccel) explain Debug-enable sample code --- maccel/readme.md | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/maccel/readme.md b/maccel/readme.md index e1895f8..90b4781 100644 --- a/maccel/readme.md +++ b/maccel/readme.md @@ -105,10 +105,13 @@ A good starting point for tweaking your settings, is to set your default DPI sli **Debug console**: To aid in dialing in your settings just right, a debug mode exists to print mathy details to the console. The debug console will print your current DPI setting and variable settings, as well as the acceleration factor, the input and output velocity, and the input and output distance. Refer to the QMK documentation on how to *enable the console and debugging*, then enable mouse acceleration debugging in `config.h`: ```c -#define MACCEL_DEBUG -/* - * Requires enabling float support for printf! +/** + * To view mouse's distance/velocity and curve parameters while configuring maccel, + * set `CONSOLE_ENABLE = yes` in `rules.mk`, uncomment the lines below, + * and run `qmk console` in the shell. + * Note: requires enabling float support for printf! */ +#define MACCEL_DEBUG #undef PRINTF_SUPPORT_DECIMAL_SPECIFIERS #define PRINTF_SUPPORT_DECIMAL_SPECIFIERS 1 ``` From 51f1691269a3414ff73d74fcfeb62a7fc556f527 Mon Sep 17 00:00:00 2001 From: Kostis Anagnostopoulos Date: Sun, 10 Mar 2024 22:21:07 +0200 Subject: [PATCH 02/11] doc(maccel) explain why low DPIs need throttling > as shown by the notebook @ 4d9235b06. --- maccel/readme.md | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/maccel/readme.md b/maccel/readme.md index 90b4781..d9c11f3 100644 --- a/maccel/readme.md +++ b/maccel/readme.md @@ -116,6 +116,14 @@ A good starting point for tweaking your settings, is to set your default DPI sli #define PRINTF_SUPPORT_DECIMAL_SPECIFIERS 1 ``` +Finally, linearity for low CPI settings works better when pointer task throttling enforces a lower frequency from the default 1ms, to have more time to gather "dots", ie. add something like this in your `config.h`: + +```c +// Reduce pointer-task frequency (1ms --> 5ms) for consistent acceleration on lower CPIs. +#undef POINTING_DEVICE_TASK_THROTTLE_MS +#define POINTING_DEVICE_TASK_THROTTLE_MS 5 +``` + ## Runtime adjusting of curve parameters by keycodes (optional) ### Additional required installation steps From 6f56b7bb03ba4bd6e20a1759b38d918e4697dce3 Mon Sep 17 00:00:00 2001 From: Kostis Anagnostopoulos Date: Sat, 2 Mar 2024 11:00:22 +0200 Subject: [PATCH 03/11] doc(maccel) denote letter-symbols & and desmos on sample params --- maccel/maccel.c | 8 ++++---- maccel/readme.md | 9 +++++---- 2 files changed, 9 insertions(+), 8 deletions(-) diff --git a/maccel/maccel.c b/maccel/maccel.c index af5bf2d..f968e7c 100644 --- a/maccel/maccel.c +++ b/maccel/maccel.c @@ -9,16 +9,16 @@ static uint32_t maccel_timer; #ifndef MACCEL_TAKEOFF -# define MACCEL_TAKEOFF 2.0 // lower/higher value = curve starts more smoothly/abruptly +# define MACCEL_TAKEOFF 2.0 // (K) lower/higher value = curve starts more smoothly/abruptly #endif #ifndef MACCEL_GROWTH_RATE -# define MACCEL_GROWTH_RATE 0.25 // lower/higher value = curve reaches its upper limit slower/faster +# define MACCEL_GROWTH_RATE 0.25 // (G) lower/higher value = curve reaches its upper limit slower/faster #endif #ifndef MACCEL_OFFSET -# define MACCEL_OFFSET 2.2 // lower/higher value = acceleration kicks in earlier/later +# define MACCEL_OFFSET 2.2 // (S) lower/higher value = acceleration kicks in earlier/later #endif #ifndef MACCEL_LIMIT -# define MACCEL_LIMIT 0.2 // lower limit of accel curve (minimum acceleration factor) +# define MACCEL_LIMIT 0.2 // (M) lower limit of accel curve (minimum acceleration factor) #endif #ifndef MACCEL_CPI_THROTTLE_MS # define MACCEL_CPI_THROTTLE_MS 200 // milliseconds to wait between requesting the device's current DPI diff --git a/maccel/readme.md b/maccel/readme.md index d9c11f3..dce3a83 100644 --- a/maccel/readme.md +++ b/maccel/readme.md @@ -80,10 +80,11 @@ Before configuring maccel, make sure you have turned off your OS acceleration se Several characteristics of the acceleration curve can be tweaked by adding relevant defines to `config.h`: ```c -#define MACCEL_TAKEOFF 2.0 // lower/higher value = curve takes off more smoothly/abruptly -#define MACCEL_GROWTH_RATE 0.25 // lower/higher value = curve reaches its upper limit slower/faster -#define MACCEL_OFFSET 2.2 // lower/higher value = acceleration kicks in earlier/later -#define MACCEL_LIMIT 0.2 // lower limit of accel curve (minimum acceleration factor) +/** Mouse acceleration curve parameters: https://www.desmos.com/calculator/g6zxh5rt44 */ +#define MACCEL_TAKEOFF 2.0 // (K) lower/higher value = curve takes off more smoothly/abruptly +#define MACCEL_GROWTH_RATE 0.25 // (G) lower/higher value = curve reaches its upper limit slower/faster +#define MACCEL_OFFSET 2.2 // (S) lower/higher value = acceleration kicks in earlier/later +#define MACCEL_LIMIT 0.2 // (M) upper limit of accel curve (maximum acceleration factor) ``` [![](assets/accel_curve.png)](https://www.desmos.com/calculator/k9vr0y2gev) From b8662f335308beb0130b87ccf56824776c989857 Mon Sep 17 00:00:00 2001 From: Kostis Anagnostopoulos Date: Sat, 2 Mar 2024 23:56:55 +0200 Subject: [PATCH 04/11] feat(maccel) stabilize debug print float widths --- maccel/maccel.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/maccel/maccel.c b/maccel/maccel.c index f968e7c..e68c162 100644 --- a/maccel/maccel.c +++ b/maccel/maccel.c @@ -157,7 +157,7 @@ report_mouse_t pointing_device_task_maccel(report_mouse_t mouse_report) { #ifdef MACCEL_DEBUG const float distance_out = sqrtf(x * x + y * y); const float velocity_out = velocity * maccel_factor; - printf("MACCEL: DPI:%4i Tko: %.3f Grw: %.3f Ofs: %.3f Lmt: %.3f | Fct: %.3f v.in: %.3f v.out: %.3f d.in: %3i d.out: %3i\n", device_cpi, g_maccel_config.takeoff, g_maccel_config.growth_rate, g_maccel_config.offset, g_maccel_config.limit, maccel_factor, velocity, velocity_out, CONSTRAIN_REPORT(distance), CONSTRAIN_REPORT(distance_out)); + printf("MACCEL: DPI:%5i Tko:%6.3f Grw:%6.3f Ofs:%6.3f Lmt:%6.3f | Fct:%7.3f v.in:%7.3f v.out:%7.3f d.in:%3i d.out:%3i\n", device_cpi, g_maccel_config.takeoff, g_maccel_config.growth_rate, g_maccel_config.offset, g_maccel_config.limit, maccel_factor, velocity, velocity_out, CONSTRAIN_REPORT(distance), CONSTRAIN_REPORT(distance_out)); #endif // MACCEL_DEBUG // report back accelerated values From ec76f8b3eeaff43e650497cbae28ff9e89eb0bf9 Mon Sep 17 00:00:00 2001 From: Kostis Anagnostopoulos Date: Sun, 3 Mar 2024 00:35:49 +0200 Subject: [PATCH 05/11] feat(maccel) debug-dump V as diffs to view carry at work and > hook the eye on +0s, use & capitalize formula letters. --- maccel/maccel.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/maccel/maccel.c b/maccel/maccel.c index e68c162..e5f6cd7 100644 --- a/maccel/maccel.c +++ b/maccel/maccel.c @@ -157,7 +157,7 @@ report_mouse_t pointing_device_task_maccel(report_mouse_t mouse_report) { #ifdef MACCEL_DEBUG const float distance_out = sqrtf(x * x + y * y); const float velocity_out = velocity * maccel_factor; - printf("MACCEL: DPI:%5i Tko:%6.3f Grw:%6.3f Ofs:%6.3f Lmt:%6.3f | Fct:%7.3f v.in:%7.3f v.out:%7.3f d.in:%3i d.out:%3i\n", device_cpi, g_maccel_config.takeoff, g_maccel_config.growth_rate, g_maccel_config.offset, g_maccel_config.limit, maccel_factor, velocity, velocity_out, CONSTRAIN_REPORT(distance), CONSTRAIN_REPORT(distance_out)); + printf("MACCEL: DPI:%5i Tko:%6.3f Grw:%6.3f Ofs:%6.3f Lmt:%6.3f | Acc:%7.3f V.in:%7.3f V.out:%+8.3f D.in:%3i D.out:%3i\n", device_cpi, g_maccel_config.takeoff, g_maccel_config.growth_rate, g_maccel_config.offset, g_maccel_config.limit, maccel_factor, velocity, velocity_out - velocity, CONSTRAIN_REPORT(distance), CONSTRAIN_REPORT(distance_out)); #endif // MACCEL_DEBUG // report back accelerated values From 9f9693b34c557621e8b3930c6f764960e9f8da74 Mon Sep 17 00:00:00 2001 From: Kostis Anagnostopoulos Date: Mon, 4 Mar 2024 18:11:47 +0200 Subject: [PATCH 06/11] fix(maccel) don't dump param-keys if DEBUG is off --- maccel/maccel.c | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/maccel/maccel.c b/maccel/maccel.c index e5f6cd7..d9187d4 100644 --- a/maccel/maccel.c +++ b/maccel/maccel.c @@ -187,22 +187,30 @@ bool process_record_maccel(uint16_t keycode, keyrecord_t *record, uint16_t toggl } if (keycode == takeoff) { maccel_set_takeoff(maccel_get_takeoff() + get_mod_step(MACCEL_TAKEOFF_STEP)); +# ifdef MACCEL_DEBUG printf("MACCEL:keycode: TKO: %.3f gro: %.3f ofs: %.3f lmt: %.3f\n", g_maccel_config.takeoff, g_maccel_config.growth_rate, g_maccel_config.offset, g_maccel_config.limit); +# endif // MACCEL_DEBUG return false; } if (keycode == growth_rate) { maccel_set_growth_rate(maccel_get_growth_rate() + get_mod_step(MACCEL_GROWTH_RATE_STEP)); +# ifdef MACCEL_DEBUG printf("MACCEL:keycode: tko: %.3f GRO: %.3f ofs: %.3f lmt: %.3f\n", g_maccel_config.takeoff, g_maccel_config.growth_rate, g_maccel_config.offset, g_maccel_config.limit); +# endif // MACCEL_DEBUG return false; } if (keycode == offset) { maccel_set_offset(maccel_get_offset() + get_mod_step(MACCEL_OFFSET_STEP)); +# ifdef MACCEL_DEBUG printf("MACCEL:keycode: tko: %.3f gro: %.3f OFS: %.3f lmt: %.3f\n", g_maccel_config.takeoff, g_maccel_config.growth_rate, g_maccel_config.offset, g_maccel_config.limit); +# endif // MACCEL_DEBUG return false; } if (keycode == limit) { maccel_set_limit(maccel_get_limit() + get_mod_step(MACCEL_LIMIT_STEP)); +# ifdef MACCEL_DEBUG printf("MACCEL:keycode: tko: %.3f gro: %.3f ofs: %.3f LMT: %.3f\n", g_maccel_config.takeoff, g_maccel_config.growth_rate, g_maccel_config.offset, g_maccel_config.limit); +# endif // MACCEL_DEBUG return false; } } From e8c6d295fb365c73f78b4dbe54a5c18e22835aef Mon Sep 17 00:00:00 2001 From: Kostis Anagnostopoulos Date: Sun, 3 Mar 2024 11:49:24 +0200 Subject: [PATCH 07/11] feat(maccel) don's reset rounding carry if not stationary --- maccel/maccel.c | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/maccel/maccel.c b/maccel/maccel.c index d9187d4..5bb95b5 100644 --- a/maccel/maccel.c +++ b/maccel/maccel.c @@ -27,7 +27,7 @@ static uint32_t maccel_timer; # define MACCEL_LIMIT_UPPER 1 // upper limit of accel curve, recommended to leave at 1; adjust DPI setting instead. #endif #ifndef MACCEL_ROUNDING_CARRY_TIMEOUT_MS -# define MACCEL_ROUNDING_CARRY_TIMEOUT_MS 200 // milliseconds after which to reset quantization error correction (forget rounding remainder) +# define MACCEL_ROUNDING_CARRY_TIMEOUT_MS 300 // Elapsed time after which quantization error gets reset. #endif maccel_config_t g_maccel_config = { @@ -110,15 +110,13 @@ report_mouse_t pointing_device_task_maccel(report_mouse_t mouse_report) { const uint16_t delta_time = timer_elapsed32(maccel_timer); // skip maccel maths if report = 0, or if maccel not enabled. if ((mouse_report.x == 0 && mouse_report.y == 0) || !g_maccel_config.enabled) { + if (delta_time > MACCEL_ROUNDING_CARRY_TIMEOUT_MS) { + rounding_carry_x = rounding_carry_y = 0; + } return mouse_report; } // reset timer: maccel_timer = timer_read32(); - // Reset carry if too much time passed - if (delta_time > MACCEL_ROUNDING_CARRY_TIMEOUT_MS) { - rounding_carry_x = 0; - rounding_carry_y = 0; - } // Reset carry when pointer swaps direction, to follow user's hand. if (mouse_report.x * rounding_carry_x < 0) rounding_carry_x = 0; if (mouse_report.y * rounding_carry_y < 0) rounding_carry_y = 0; From 1d285dea890bd5ef7ec48fd6128a36ebdc852a64 Mon Sep 17 00:00:00 2001 From: Kostis Anagnostopoulos Date: Mon, 11 Mar 2024 12:06:09 +0200 Subject: [PATCH 08/11] refact(maccel) demote timer from module-static -> function, > doc: minor explain-docs in main func. --- maccel/maccel.c | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/maccel/maccel.c b/maccel/maccel.c index 5bb95b5..d7a28c2 100644 --- a/maccel/maccel.c +++ b/maccel/maccel.c @@ -6,8 +6,6 @@ #include "maccel.h" #include "math.h" -static uint32_t maccel_timer; - #ifndef MACCEL_TAKEOFF # define MACCEL_TAKEOFF 2.0 // (K) lower/higher value = curve starts more smoothly/abruptly #endif @@ -103,6 +101,7 @@ void maccel_toggle_enabled(void) { #define CONSTRAIN_REPORT(val) (mouse_xy_report_t) _CONSTRAIN(val, XY_REPORT_MIN, XY_REPORT_MAX) report_mouse_t pointing_device_task_maccel(report_mouse_t mouse_report) { + static uint32_t maccel_timer = 0; // rounding carry to recycle dropped floats from int mouse reports, to smoothen low speed movements (credit @ankostis) static float rounding_carry_x = 0; static float rounding_carry_y = 0; @@ -115,12 +114,12 @@ report_mouse_t pointing_device_task_maccel(report_mouse_t mouse_report) { } return mouse_report; } - // reset timer: + // Reset timer on non-zero reports. maccel_timer = timer_read32(); // Reset carry when pointer swaps direction, to follow user's hand. if (mouse_report.x * rounding_carry_x < 0) rounding_carry_x = 0; if (mouse_report.y * rounding_carry_y < 0) rounding_carry_y = 0; - // Limit expensive calls to get device cpi settings only when mouse stationary for > 200ms. + // Limit expensive calls to get device cpi settings only when mouse stationary for some time. static uint16_t device_cpi = 300; if (delta_time > MACCEL_CPI_THROTTLE_MS) { device_cpi = pointing_device_get_cpi(); From 08173314ef85cf1c86a3b7fb97c0a968720d2397 Mon Sep 17 00:00:00 2001 From: Kostis Anagnostopoulos Date: Tue, 12 Mar 2024 12:20:05 +0200 Subject: [PATCH 09/11] refact(maccel) explain x1000 factor as curve-fitting, > cluster configurable/curve params. --- maccel/maccel.c | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) diff --git a/maccel/maccel.c b/maccel/maccel.c index d7a28c2..637f620 100644 --- a/maccel/maccel.c +++ b/maccel/maccel.c @@ -18,15 +18,22 @@ #ifndef MACCEL_LIMIT # define MACCEL_LIMIT 0.2 // (M) lower limit of accel curve (minimum acceleration factor) #endif -#ifndef MACCEL_CPI_THROTTLE_MS -# define MACCEL_CPI_THROTTLE_MS 200 // milliseconds to wait between requesting the device's current DPI -#endif #ifndef MACCEL_LIMIT_UPPER # define MACCEL_LIMIT_UPPER 1 // upper limit of accel curve, recommended to leave at 1; adjust DPI setting instead. #endif +#ifndef MACCEL_CPI_THROTTLE_MS +# define MACCEL_CPI_THROTTLE_MS 200 // milliseconds to wait between requesting the device's current DPI +#endif #ifndef MACCEL_ROUNDING_CARRY_TIMEOUT_MS # define MACCEL_ROUNDING_CARRY_TIMEOUT_MS 300 // Elapsed time after which quantization error gets reset. #endif +/** + * Scale acceleration curve's v-input so that its params are not uncannily small + * and floats do not overflow in the accel formula (eg. `exp(709.8)` for doubles). + * Eventually the accel formula is calculated as if the pointer reports @ 1000 CPI, + * but "counts" are expressed as float (vs integer for the hw "counts"). + */ +#define MACCEL_MAGNIFICATION_DPI 1000.0 maccel_config_t g_maccel_config = { // clang-format off @@ -125,7 +132,7 @@ report_mouse_t pointing_device_task_maccel(report_mouse_t mouse_report) { device_cpi = pointing_device_get_cpi(); } // calculate dpi correction factor (for normalizing velocity range across different user dpi settings) - const float dpi_correction = (float)1000.0f / device_cpi; + const float dpi_correction = (float)MACCEL_MAGNIFICATION_DPI / device_cpi; // calculate euclidean distance moved (sqrt(x^2 + y^2)) const float distance = sqrtf(mouse_report.x * mouse_report.x + mouse_report.y * mouse_report.y); // calculate delta velocity: dv = distance/dt From e164bc33b800cbe352f48b4bcbbc1513aabe9aac Mon Sep 17 00:00:00 2001 From: Kostis Anagnostopoulos Date: Tue, 12 Mar 2024 17:40:56 +0200 Subject: [PATCH 10/11] feat(maccel) debug-dump D as diffs to hook the eye on 0s --- maccel/maccel.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/maccel/maccel.c b/maccel/maccel.c index 637f620..f356845 100644 --- a/maccel/maccel.c +++ b/maccel/maccel.c @@ -161,7 +161,7 @@ report_mouse_t pointing_device_task_maccel(report_mouse_t mouse_report) { #ifdef MACCEL_DEBUG const float distance_out = sqrtf(x * x + y * y); const float velocity_out = velocity * maccel_factor; - printf("MACCEL: DPI:%5i Tko:%6.3f Grw:%6.3f Ofs:%6.3f Lmt:%6.3f | Acc:%7.3f V.in:%7.3f V.out:%+8.3f D.in:%3i D.out:%3i\n", device_cpi, g_maccel_config.takeoff, g_maccel_config.growth_rate, g_maccel_config.offset, g_maccel_config.limit, maccel_factor, velocity, velocity_out - velocity, CONSTRAIN_REPORT(distance), CONSTRAIN_REPORT(distance_out)); + printf("MACCEL: DPI:%5i Tko:%6.3f Grw:%6.3f Ofs:%6.3f Lmt:%6.3f | Acc:%7.3f V.in:%7.3f V.out:%+8.3f D.in:%3i D.out:%+8.3f\n", device_cpi, g_maccel_config.takeoff, g_maccel_config.growth_rate, g_maccel_config.offset, g_maccel_config.limit, maccel_factor, velocity, velocity_out - velocity, CONSTRAIN_REPORT(distance), distance_out - CONSTRAIN_REPORT(distance)); #endif // MACCEL_DEBUG // report back accelerated values From 426ba616e9aa63b5fed09b7c966aa39bb124722f Mon Sep 17 00:00:00 2001 From: Kostis Anagnostopoulos Date: Tue, 12 Mar 2024 13:16:47 +0200 Subject: [PATCH 11/11] style(maccel) minor comment move --- maccel/maccel.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/maccel/maccel.c b/maccel/maccel.c index f356845..9e43c2f 100644 --- a/maccel/maccel.c +++ b/maccel/maccel.c @@ -157,8 +157,8 @@ report_mouse_t pointing_device_task_maccel(report_mouse_t mouse_report) { const mouse_xy_report_t x = CONSTRAIN_REPORT(new_x); const mouse_xy_report_t y = CONSTRAIN_REPORT(new_y); -// console output for debugging (enable/disable in config.h) #ifdef MACCEL_DEBUG + // console output for debugging (enable/disable in config.h) const float distance_out = sqrtf(x * x + y * y); const float velocity_out = velocity * maccel_factor; printf("MACCEL: DPI:%5i Tko:%6.3f Grw:%6.3f Ofs:%6.3f Lmt:%6.3f | Acc:%7.3f V.in:%7.3f V.out:%+8.3f D.in:%3i D.out:%+8.3f\n", device_cpi, g_maccel_config.takeoff, g_maccel_config.growth_rate, g_maccel_config.offset, g_maccel_config.limit, maccel_factor, velocity, velocity_out - velocity, CONSTRAIN_REPORT(distance), distance_out - CONSTRAIN_REPORT(distance));