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

Commit a5b06982 authored by Jeff Brown's avatar Jeff Brown
Browse files

Implement a second order integrating VT strategy.

Bug: 6413587
Change-Id: I51bc7b8cbff22b10b728fc84ee15370e9984dd55
parent 18f329e9
Loading
Loading
Loading
Loading
+9 −7
Original line number Original line Diff line number Diff line
@@ -196,7 +196,8 @@ private:
 */
 */
class IntegratingVelocityTrackerStrategy : public VelocityTrackerStrategy {
class IntegratingVelocityTrackerStrategy : public VelocityTrackerStrategy {
public:
public:
    IntegratingVelocityTrackerStrategy();
    // Degree must be 1 or 2.
    IntegratingVelocityTrackerStrategy(uint32_t degree);
    ~IntegratingVelocityTrackerStrategy();
    ~IntegratingVelocityTrackerStrategy();


    virtual void clear();
    virtual void clear();
@@ -209,18 +210,19 @@ private:
    // Current state estimate for a particular pointer.
    // Current state estimate for a particular pointer.
    struct State {
    struct State {
        nsecs_t updateTime;
        nsecs_t updateTime;
        bool first;
        uint32_t degree;


        float xpos, xvel;
        float xpos, xvel, xaccel;
        float ypos, yvel;
        float ypos, yvel, yaccel;
    };
    };


    const uint32_t mDegree;
    BitSet32 mPointerIdBits;
    BitSet32 mPointerIdBits;
    State mPointerState[MAX_POINTER_ID + 1];
    State mPointerState[MAX_POINTER_ID + 1];


    static void initState(State& state, nsecs_t eventTime, float xpos, float ypos);
    void initState(State& state, nsecs_t eventTime, float xpos, float ypos) const;
    static void updateState(State& state, nsecs_t eventTime, float xpos, float ypos);
    void updateState(State& state, nsecs_t eventTime, float xpos, float ypos) const;
    static void populateEstimator(const State& state, VelocityTracker::Estimator* outEstimator);
    void populateEstimator(const State& state, VelocityTracker::Estimator* outEstimator) const;
};
};


} // namespace android
} // namespace android
+37 −11
Original line number Original line Diff line number Diff line
@@ -182,7 +182,13 @@ VelocityTrackerStrategy* VelocityTracker::createStrategy(const char* strategy) {
        // more tolerant of errors.  Like 'lsq1', this strategy tends to underestimate
        // more tolerant of errors.  Like 'lsq1', this strategy tends to underestimate
        // the velocity of a fling but this strategy tends to respond to changes in
        // the velocity of a fling but this strategy tends to respond to changes in
        // direction more quickly and accurately.
        // direction more quickly and accurately.
        return new IntegratingVelocityTrackerStrategy();
        return new IntegratingVelocityTrackerStrategy(1);
    }
    if (!strcmp("int2", strategy)) {
        // 2nd order integrating filter.  Quality: EXPERIMENTAL.
        // For comparison purposes only.  Unlike 'int1' this strategy can compensate
        // for acceleration but it typically overestimates the effect.
        return new IntegratingVelocityTrackerStrategy(2);
    }
    }
    return NULL;
    return NULL;
}
}
@@ -680,7 +686,8 @@ float LeastSquaresVelocityTrackerStrategy::chooseWeight(uint32_t index) const {


// --- IntegratingVelocityTrackerStrategy ---
// --- IntegratingVelocityTrackerStrategy ---


IntegratingVelocityTrackerStrategy::IntegratingVelocityTrackerStrategy() {
IntegratingVelocityTrackerStrategy::IntegratingVelocityTrackerStrategy(uint32_t degree) :
        mDegree(degree) {
}
}


IntegratingVelocityTrackerStrategy::~IntegratingVelocityTrackerStrategy() {
IntegratingVelocityTrackerStrategy::~IntegratingVelocityTrackerStrategy() {
@@ -725,18 +732,20 @@ bool IntegratingVelocityTrackerStrategy::getEstimator(uint32_t id,
}
}


void IntegratingVelocityTrackerStrategy::initState(State& state,
void IntegratingVelocityTrackerStrategy::initState(State& state,
        nsecs_t eventTime, float xpos, float ypos) {
        nsecs_t eventTime, float xpos, float ypos) const {
    state.updateTime = eventTime;
    state.updateTime = eventTime;
    state.first = true;
    state.degree = 0;


    state.xpos = xpos;
    state.xpos = xpos;
    state.xvel = 0;
    state.xvel = 0;
    state.xaccel = 0;
    state.ypos = ypos;
    state.ypos = ypos;
    state.yvel = 0;
    state.yvel = 0;
    state.yaccel = 0;
}
}


void IntegratingVelocityTrackerStrategy::updateState(State& state,
void IntegratingVelocityTrackerStrategy::updateState(State& state,
        nsecs_t eventTime, float xpos, float ypos) {
        nsecs_t eventTime, float xpos, float ypos) const {
    const nsecs_t MIN_TIME_DELTA = 2 * NANOS_PER_MS;
    const nsecs_t MIN_TIME_DELTA = 2 * NANOS_PER_MS;
    const float FILTER_TIME_CONSTANT = 0.010f; // 10 milliseconds
    const float FILTER_TIME_CONSTANT = 0.010f; // 10 milliseconds


@@ -749,28 +758,45 @@ void IntegratingVelocityTrackerStrategy::updateState(State& state,


    float xvel = (xpos - state.xpos) / dt;
    float xvel = (xpos - state.xpos) / dt;
    float yvel = (ypos - state.ypos) / dt;
    float yvel = (ypos - state.ypos) / dt;
    if (state.first) {
    if (state.degree == 0) {
        state.xvel = xvel;
        state.xvel = xvel;
        state.yvel = yvel;
        state.yvel = yvel;
        state.first = false;
        state.degree = 1;
    } else {
    } else {
        float alpha = dt / (FILTER_TIME_CONSTANT + dt);
        float alpha = dt / (FILTER_TIME_CONSTANT + dt);
        if (mDegree == 1) {
            state.xvel += (xvel - state.xvel) * alpha;
            state.xvel += (xvel - state.xvel) * alpha;
            state.yvel += (yvel - state.yvel) * alpha;
            state.yvel += (yvel - state.yvel) * alpha;
        } else {
            float xaccel = (xvel - state.xvel) / dt;
            float yaccel = (yvel - state.yvel) / dt;
            if (state.degree == 1) {
                state.xaccel = xaccel;
                state.yaccel = yaccel;
                state.degree = 2;
            } else {
                state.xaccel += (xaccel - state.xaccel) * alpha;
                state.yaccel += (yaccel - state.yaccel) * alpha;
            }
            state.xvel += (state.xaccel * dt) * alpha;
            state.yvel += (state.yaccel * dt) * alpha;
        }
    }
    }
    state.xpos = xpos;
    state.xpos = xpos;
    state.ypos = ypos;
    state.ypos = ypos;
}
}


void IntegratingVelocityTrackerStrategy::populateEstimator(const State& state,
void IntegratingVelocityTrackerStrategy::populateEstimator(const State& state,
        VelocityTracker::Estimator* outEstimator) {
        VelocityTracker::Estimator* outEstimator) const {
    outEstimator->time = state.updateTime;
    outEstimator->time = state.updateTime;
    outEstimator->degree = 1;
    outEstimator->confidence = 1.0f;
    outEstimator->confidence = 1.0f;
    outEstimator->degree = state.degree;
    outEstimator->xCoeff[0] = state.xpos;
    outEstimator->xCoeff[0] = state.xpos;
    outEstimator->xCoeff[1] = state.xvel;
    outEstimator->xCoeff[1] = state.xvel;
    outEstimator->xCoeff[2] = state.xaccel / 2;
    outEstimator->yCoeff[0] = state.ypos;
    outEstimator->yCoeff[0] = state.ypos;
    outEstimator->yCoeff[1] = state.yvel;
    outEstimator->yCoeff[1] = state.yvel;
    outEstimator->yCoeff[2] = state.yaccel / 2;
}
}


} // namespace android
} // namespace android