Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 3803f0b5 authored by Treehugger Robot's avatar Treehugger Robot Committed by Gerrit Code Review
Browse files

Merge "Movement estimates for pointer location"

parents 38faea68 e96bc7ab
Loading
Loading
Loading
Loading
+1 −0
Original line number Original line Diff line number Diff line
@@ -16,6 +16,7 @@


cc_library {
cc_library {
    name: "libinput",
    name: "libinput",
    cpp_std: "c++17",
    host_supported: true,
    host_supported: true,
    cflags: [
    cflags: [
        "-Wall",
        "-Wall",
+31 −14
Original line number Original line Diff line number Diff line
@@ -23,9 +23,11 @@
// Log debug messages about the progress of the algorithm itself.
// Log debug messages about the progress of the algorithm itself.
#define DEBUG_STRATEGY 0
#define DEBUG_STRATEGY 0


#include <array>
#include <inttypes.h>
#include <inttypes.h>
#include <limits.h>
#include <limits.h>
#include <math.h>
#include <math.h>
#include <optional>


#include <android-base/stringprintf.h>
#include <android-base/stringprintf.h>
#include <cutils/properties.h>
#include <cutils/properties.h>
@@ -564,7 +566,9 @@ static bool solveLeastSquares(const float* x, const float* y,
 * Optimized unweighted second-order least squares fit. About 2x speed improvement compared to
 * Optimized unweighted second-order least squares fit. About 2x speed improvement compared to
 * the default implementation
 * the default implementation
 */
 */
static float solveUnweightedLeastSquaresDeg2(const float* x, const float* y, size_t count) {
static std::optional<std::array<float, 3>> solveUnweightedLeastSquaresDeg2(
        const float* x, const float* y, size_t count) {
    // Solving y = a*x^2 + b*x + c
    float sxi = 0, sxiyi = 0, syi = 0, sxi2 = 0, sxi3 = 0, sxi2yi = 0, sxi4 = 0;
    float sxi = 0, sxiyi = 0, syi = 0, sxi2 = 0, sxi3 = 0, sxi2yi = 0, sxi4 = 0;


    for (size_t i = 0; i < count; i++) {
    for (size_t i = 0; i < count; i++) {
@@ -573,8 +577,8 @@ static float solveUnweightedLeastSquaresDeg2(const float* x, const float* y, siz
        float xi2 = xi*xi;
        float xi2 = xi*xi;
        float xi3 = xi2*xi;
        float xi3 = xi2*xi;
        float xi4 = xi3*xi;
        float xi4 = xi3*xi;
        float xi2yi = xi2*yi;
        float xiyi = xi*yi;
        float xiyi = xi*yi;
        float xi2yi = xi2*yi;


        sxi += xi;
        sxi += xi;
        sxi2 += xi2;
        sxi2 += xi2;
@@ -591,13 +595,23 @@ static float solveUnweightedLeastSquaresDeg2(const float* x, const float* y, siz
    float Sx2y = sxi2yi - sxi2*syi / count;
    float Sx2y = sxi2yi - sxi2*syi / count;
    float Sx2x2 = sxi4 - sxi2*sxi2 / count;
    float Sx2x2 = sxi4 - sxi2*sxi2 / count;


    float numerator = Sxy*Sx2x2 - Sx2y*Sxx2;
    float denominator = Sxx*Sx2x2 - Sxx2*Sxx2;
    float denominator = Sxx*Sx2x2 - Sxx2*Sxx2;
    if (denominator == 0) {
    if (denominator == 0) {
        ALOGW("division by 0 when computing velocity, Sxx=%f, Sx2x2=%f, Sxx2=%f", Sxx, Sx2x2, Sxx2);
        ALOGW("division by 0 when computing velocity, Sxx=%f, Sx2x2=%f, Sxx2=%f", Sxx, Sx2x2, Sxx2);
        return 0;
        return std::nullopt;
    }
    }
    return numerator/denominator;
    // Compute a
    float numerator = Sx2y*Sxx - Sxy*Sxx2;
    float a = numerator / denominator;

    // Compute b
    numerator = Sxy*Sx2x2 - Sx2y*Sxx2;
    float b = numerator / denominator;

    // Compute c
    float c = syi/count - b * sxi/count - a * sxi2/count;

    return std::make_optional(std::array<float, 3>({c, b, a}));
}
}


bool LeastSquaresVelocityTrackerStrategy::getEstimator(uint32_t id,
bool LeastSquaresVelocityTrackerStrategy::getEstimator(uint32_t id,
@@ -640,20 +654,23 @@ bool LeastSquaresVelocityTrackerStrategy::getEstimator(uint32_t id,
    if (degree > m - 1) {
    if (degree > m - 1) {
        degree = m - 1;
        degree = m - 1;
    }
    }
    if (degree >= 1) {

        if (degree == 2 && mWeighting == WEIGHTING_NONE) { // optimize unweighted, degree=2 fit
    if (degree == 2 && mWeighting == WEIGHTING_NONE) {
        // Optimize unweighted, quadratic polynomial fit
        std::optional<std::array<float, 3>> xCoeff = solveUnweightedLeastSquaresDeg2(time, x, m);
        std::optional<std::array<float, 3>> yCoeff = solveUnweightedLeastSquaresDeg2(time, y, m);
        if (xCoeff && yCoeff) {
            outEstimator->time = newestMovement.eventTime;
            outEstimator->time = newestMovement.eventTime;
            outEstimator->degree = 2;
            outEstimator->degree = 2;
            outEstimator->confidence = 1;
            outEstimator->confidence = 1;
            outEstimator->xCoeff[0] = 0; // only slope is calculated, set rest of coefficients = 0
            for (size_t i = 0; i <= outEstimator->degree; i++) {
            outEstimator->yCoeff[0] = 0;
                outEstimator->xCoeff[i] = (*xCoeff)[i];
            outEstimator->xCoeff[1] = solveUnweightedLeastSquaresDeg2(time, x, m);
                outEstimator->yCoeff[i] = (*yCoeff)[i];
            outEstimator->yCoeff[1] = solveUnweightedLeastSquaresDeg2(time, y, m);
            }
            outEstimator->xCoeff[2] = 0;
            outEstimator->yCoeff[2] = 0;
            return true;
            return true;
        }
        }

    } else if (degree >= 1) {
        // General case for an Nth degree polynomial fit
        float xdet, ydet;
        float xdet, ydet;
        uint32_t n = degree + 1;
        uint32_t n = degree + 1;
        if (solveLeastSquares(time, x, w, m, n, outEstimator->xCoeff, &xdet)
        if (solveLeastSquares(time, x, w, m, n, outEstimator->xCoeff, &xdet)