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

Commit be67e2e1 authored by TreeHugger Robot's avatar TreeHugger Robot Committed by Android (Google) Code Review
Browse files

Merge "Use constexpr in VelocityTracker"

parents ccfc0b73 e37bcece
Loading
Loading
Loading
Loading
+71 −69
Original line number Diff line number Diff line
@@ -18,10 +18,10 @@
//#define LOG_NDEBUG 0

// Log debug messages about velocity tracking.
#define DEBUG_VELOCITY 0
static constexpr bool DEBUG_VELOCITY = false;

// Log debug messages about the progress of the algorithm itself.
#define DEBUG_STRATEGY 0
static constexpr bool DEBUG_STRATEGY = false;

#include <array>
#include <inttypes.h>
@@ -30,7 +30,6 @@
#include <optional>

#include <android-base/stringprintf.h>
#include <cutils/properties.h>
#include <input/VelocityTracker.h>
#include <utils/BitSet.h>
#include <utils/Timers.h>
@@ -64,7 +63,6 @@ static float vectorNorm(const float* a, uint32_t m) {
    return sqrtf(r);
}

#if DEBUG_STRATEGY || DEBUG_VELOCITY
static std::string vectorToString(const float* a, uint32_t m) {
    std::string str;
    str += "[";
@@ -77,9 +75,11 @@ static std::string vectorToString(const float* a, uint32_t m) {
    str += " ]";
    return str;
}
#endif

#if DEBUG_STRATEGY
static std::string vectorToString(const std::vector<float>& v) {
    return vectorToString(v.data(), v.size());
}

static std::string matrixToString(const float* a, uint32_t m, uint32_t n, bool rowMajor) {
    std::string str;
    str = "[";
@@ -99,7 +99,6 @@ static std::string matrixToString(const float* a, uint32_t m, uint32_t n, bool r
    str += " ]";
    return str;
}
#endif


// --- VelocityTracker ---
@@ -133,12 +132,18 @@ std::unique_ptr<VelocityTrackerStrategy> VelocityTracker::createStrategy(
        VelocityTracker::Strategy strategy) {
    switch (strategy) {
        case VelocityTracker::Strategy::IMPULSE:
            if (DEBUG_STRATEGY) {
                ALOGI("Initializing impulse strategy");
            }
            return std::make_unique<ImpulseVelocityTrackerStrategy>();

        case VelocityTracker::Strategy::LSQ1:
            return std::make_unique<LeastSquaresVelocityTrackerStrategy>(1);

        case VelocityTracker::Strategy::LSQ2:
            if (DEBUG_STRATEGY) {
                ALOGI("Initializing lsq2 strategy");
            }
            return std::make_unique<LeastSquaresVelocityTrackerStrategy>(2);

        case VelocityTracker::Strategy::LSQ3:
@@ -204,10 +209,10 @@ void VelocityTracker::addMovement(nsecs_t eventTime, BitSet32 idBits,

    if ((mCurrentPointerIdBits.value & idBits.value)
            && eventTime >= mLastEventTime + ASSUME_POINTER_STOPPED_TIME) {
#if DEBUG_VELOCITY
        if (DEBUG_VELOCITY) {
            ALOGD("VelocityTracker: stopped for %0.3f ms, clearing state.",
                  (eventTime - mLastEventTime) * 0.000001f);
#endif
        }
        // We have not received any movements for too long.  Assume that all pointers
        // have stopped.
        mStrategy->clear();
@@ -221,8 +226,9 @@ void VelocityTracker::addMovement(nsecs_t eventTime, BitSet32 idBits,

    mStrategy->addMovement(eventTime, idBits, positions);

#if DEBUG_VELOCITY
    ALOGD("VelocityTracker: addMovement eventTime=%" PRId64 ", idBits=0x%08x, activePointerId=%d",
    if (DEBUG_VELOCITY) {
        ALOGD("VelocityTracker: addMovement eventTime=%" PRId64
              ", idBits=0x%08x, activePointerId=%d",
              eventTime, idBits.value, mActivePointerId);
        for (BitSet32 iterBits(idBits); !iterBits.isEmpty();) {
            uint32_t id = iterBits.firstMarkedBit();
@@ -232,13 +238,12 @@ void VelocityTracker::addMovement(nsecs_t eventTime, BitSet32 idBits,
            getEstimator(id, &estimator);
            ALOGD("  %d: position (%0.3f, %0.3f), "
                  "estimator (degree=%d, xCoeff=%s, yCoeff=%s, confidence=%f)",
                id, positions[index].x, positions[index].y,
                int(estimator.degree),
                  id, positions[index].x, positions[index].y, int(estimator.degree),
                  vectorToString(estimator.xCoeff, estimator.degree + 1).c_str(),
                  vectorToString(estimator.yCoeff, estimator.degree + 1).c_str(),
                  estimator.confidence);
        }
#endif
    }
}

void VelocityTracker::addMovement(const MotionEvent* event) {
@@ -419,11 +424,10 @@ void LeastSquaresVelocityTrackerStrategy::addMovement(
static bool solveLeastSquares(const std::vector<float>& x, const std::vector<float>& y,
                              const std::vector<float>& w, uint32_t n, float* outB, float* outDet) {
    const size_t m = x.size();
#if DEBUG_STRATEGY
    if (DEBUG_STRATEGY) {
        ALOGD("solveLeastSquares: m=%d, n=%d, x=%s, y=%s, w=%s", int(m), int(n),
            vectorToString(x, m).c_str(), vectorToString(y, m).c_str(),
            vectorToString(w, m).c_str());
#endif
              vectorToString(x).c_str(), vectorToString(y).c_str(), vectorToString(w).c_str());
    }
    LOG_ALWAYS_FATAL_IF(m != y.size() || m != w.size(), "Mismatched vector sizes");

    // Expand the X vector to a matrix A, pre-multiplied by the weights.
@@ -434,9 +438,9 @@ static bool solveLeastSquares(const std::vector<float>& x, const std::vector<flo
            a[i][h] = a[i - 1][h] * x[h];
        }
    }
#if DEBUG_STRATEGY
    if (DEBUG_STRATEGY) {
        ALOGD("  - a=%s", matrixToString(&a[0][0], m, n, false /*rowMajor*/).c_str());
#endif
    }

    // Apply the Gram-Schmidt process to A to obtain its QR decomposition.
    float q[n][m]; // orthonormal basis, column-major order
@@ -455,9 +459,9 @@ static bool solveLeastSquares(const std::vector<float>& x, const std::vector<flo
        float norm = vectorNorm(&q[j][0], m);
        if (norm < 0.000001f) {
            // vectors are linearly dependent or zero so no solution
#if DEBUG_STRATEGY
            if (DEBUG_STRATEGY) {
                ALOGD("  - no solution, norm=%f", norm);
#endif
            }
            return false;
        }

@@ -469,7 +473,7 @@ static bool solveLeastSquares(const std::vector<float>& x, const std::vector<flo
            r[j][i] = i < j ? 0 : vectorDot(&q[j][0], &a[i][0], m);
        }
    }
#if DEBUG_STRATEGY
    if (DEBUG_STRATEGY) {
        ALOGD("  - q=%s", matrixToString(&q[0][0], m, n, false /*rowMajor*/).c_str());
        ALOGD("  - r=%s", matrixToString(&r[0][0], n, n, true /*rowMajor*/).c_str());

@@ -484,7 +488,7 @@ static bool solveLeastSquares(const std::vector<float>& x, const std::vector<flo
            }
        }
        ALOGD("  - qr=%s", matrixToString(&qr[0][0], m, n, false /*rowMajor*/).c_str());
#endif
    }

    // Solve R B = Qt W Y to find B.  This is easy because R is upper triangular.
    // We just work from bottom-right to top-left calculating B's coefficients.
@@ -500,9 +504,9 @@ static bool solveLeastSquares(const std::vector<float>& x, const std::vector<flo
        }
        outB[i] /= r[i][i];
    }
#if DEBUG_STRATEGY
    if (DEBUG_STRATEGY) {
        ALOGD("  - b=%s", vectorToString(outB, n).c_str());
#endif
    }

    // Calculate the coefficient of determination as 1 - (SSerr / SStot) where
    // SSerr is the residual sum of squares (variance of the error),
@@ -528,11 +532,11 @@ static bool solveLeastSquares(const std::vector<float>& x, const std::vector<flo
        sstot += w[h] * w[h] * var * var;
    }
    *outDet = sstot > 0.000001f ? 1.0f - (sserr / sstot) : 1;
#if DEBUG_STRATEGY
    if (DEBUG_STRATEGY) {
        ALOGD("  - sserr=%f", sserr);
        ALOGD("  - sstot=%f", sstot);
        ALOGD("  - det=%f", *outDet);
#endif
    }
    return true;
}

@@ -655,13 +659,11 @@ bool LeastSquaresVelocityTrackerStrategy::getEstimator(uint32_t id,
            outEstimator->time = newestMovement.eventTime;
            outEstimator->degree = degree;
            outEstimator->confidence = xdet * ydet;
#if DEBUG_STRATEGY
            if (DEBUG_STRATEGY) {
                ALOGD("estimate: degree=%d, xCoeff=%s, yCoeff=%s, confidence=%f",
                    int(outEstimator->degree),
                    vectorToString(outEstimator->xCoeff, n).c_str(),
                    vectorToString(outEstimator->yCoeff, n).c_str(),
                    outEstimator->confidence);
#endif
                      int(outEstimator->degree), vectorToString(outEstimator->xCoeff, n).c_str(),
                      vectorToString(outEstimator->yCoeff, n).c_str(), outEstimator->confidence);
            }
            return true;
        }
    }
@@ -1169,9 +1171,9 @@ bool ImpulseVelocityTrackerStrategy::getEstimator(uint32_t id,
    outEstimator->time = newestMovement.eventTime;
    outEstimator->degree = 2; // similar results to 2nd degree fit
    outEstimator->confidence = 1;
#if DEBUG_STRATEGY
    if (DEBUG_STRATEGY) {
        ALOGD("velocity: (%f, %f)", outEstimator->xCoeff[1], outEstimator->yCoeff[1]);
#endif
    }
    return true;
}

+1 −1
Original line number Diff line number Diff line
@@ -343,7 +343,7 @@ TEST_F(VelocityTrackerTest, SailfishFlingUpSlow1) {
        { 235089162955851ns, {{560.66, 843.82}} }, // ACTION_UP
    };
    computeAndCheckVelocity(VelocityTracker::Strategy::IMPULSE, motions, AMOTION_EVENT_AXIS_X,
                            872.794617);
                            764.345703);
    computeAndCheckVelocity(VelocityTracker::Strategy::LSQ2, motions, AMOTION_EVENT_AXIS_X,
                            951.698181);
    computeAndCheckVelocity(VelocityTracker::Strategy::IMPULSE, motions, AMOTION_EVENT_AXIS_Y,