You can not select more than 25 topics
			Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
		
		
		
		
			
				
					270 lines
				
				8.6 KiB
			
		
		
			
		
	
	
					270 lines
				
				8.6 KiB
			| 
								 
											6 years ago
										 
									 | 
							
								/*
							 | 
						||
| 
								 | 
							
								 * Copyright (C) 2012 The Android Open Source Project
							 | 
						||
| 
								 | 
							
								 *
							 | 
						||
| 
								 | 
							
								 * Licensed under the Apache License, Version 2.0 (the "License");
							 | 
						||
| 
								 | 
							
								 * you may not use this file except in compliance with the License.
							 | 
						||
| 
								 | 
							
								 * You may obtain a copy of the License at
							 | 
						||
| 
								 | 
							
								 *
							 | 
						||
| 
								 | 
							
								 *      http://www.apache.org/licenses/LICENSE-2.0
							 | 
						||
| 
								 | 
							
								 *
							 | 
						||
| 
								 | 
							
								 * Unless required by applicable law or agreed to in writing, software
							 | 
						||
| 
								 | 
							
								 * distributed under the License is distributed on an "AS IS" BASIS,
							 | 
						||
| 
								 | 
							
								 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
							 | 
						||
| 
								 | 
							
								 * See the License for the specific language governing permissions and
							 | 
						||
| 
								 | 
							
								 * limitations under the License.
							 | 
						||
| 
								 | 
							
								 */
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								#ifndef _LIBINPUT_VELOCITY_TRACKER_H
							 | 
						||
| 
								 | 
							
								#define _LIBINPUT_VELOCITY_TRACKER_H
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								#include <input/Input.h>
							 | 
						||
| 
								 | 
							
								#include <utils/Timers.h>
							 | 
						||
| 
								 | 
							
								#include <utils/BitSet.h>
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								namespace android {
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								class VelocityTrackerStrategy;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								/*
							 | 
						||
| 
								 | 
							
								 * Calculates the velocity of pointer movements over time.
							 | 
						||
| 
								 | 
							
								 */
							 | 
						||
| 
								 | 
							
								class VelocityTracker {
							 | 
						||
| 
								 | 
							
								public:
							 | 
						||
| 
								 | 
							
								    struct Position {
							 | 
						||
| 
								 | 
							
								        float x, y;
							 | 
						||
| 
								 | 
							
								    };
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    struct Estimator {
							 | 
						||
| 
								 | 
							
								        static const size_t MAX_DEGREE = 4;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        // Estimator time base.
							 | 
						||
| 
								 | 
							
								        nsecs_t time;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        // Polynomial coefficients describing motion in X and Y.
							 | 
						||
| 
								 | 
							
								        float xCoeff[MAX_DEGREE + 1], yCoeff[MAX_DEGREE + 1];
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        // Polynomial degree (number of coefficients), or zero if no information is
							 | 
						||
| 
								 | 
							
								        // available.
							 | 
						||
| 
								 | 
							
								        uint32_t degree;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        // Confidence (coefficient of determination), between 0 (no fit) and 1 (perfect fit).
							 | 
						||
| 
								 | 
							
								        float confidence;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        inline void clear() {
							 | 
						||
| 
								 | 
							
								            time = 0;
							 | 
						||
| 
								 | 
							
								            degree = 0;
							 | 
						||
| 
								 | 
							
								            confidence = 0;
							 | 
						||
| 
								 | 
							
								            for (size_t i = 0; i <= MAX_DEGREE; i++) {
							 | 
						||
| 
								 | 
							
								                xCoeff[i] = 0;
							 | 
						||
| 
								 | 
							
								                yCoeff[i] = 0;
							 | 
						||
| 
								 | 
							
								            }
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								    };
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    // Creates a velocity tracker using the specified strategy.
							 | 
						||
| 
								 | 
							
								    // If strategy is NULL, uses the default strategy for the platform.
							 | 
						||
| 
								 | 
							
								    VelocityTracker(const char* strategy = NULL);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    ~VelocityTracker();
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    // Resets the velocity tracker state.
							 | 
						||
| 
								 | 
							
								    void clear();
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    // Resets the velocity tracker state for specific pointers.
							 | 
						||
| 
								 | 
							
								    // Call this method when some pointers have changed and may be reusing
							 | 
						||
| 
								 | 
							
								    // an id that was assigned to a different pointer earlier.
							 | 
						||
| 
								 | 
							
								    void clearPointers(BitSet32 idBits);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    // Adds movement information for a set of pointers.
							 | 
						||
| 
								 | 
							
								    // The idBits bitfield specifies the pointer ids of the pointers whose positions
							 | 
						||
| 
								 | 
							
								    // are included in the movement.
							 | 
						||
| 
								 | 
							
								    // The positions array contains position information for each pointer in order by
							 | 
						||
| 
								 | 
							
								    // increasing id.  Its size should be equal to the number of one bits in idBits.
							 | 
						||
| 
								 | 
							
								    void addMovement(nsecs_t eventTime, BitSet32 idBits, const Position* positions);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    // Adds movement information for all pointers in a MotionEvent, including historical samples.
							 | 
						||
| 
								 | 
							
								    void addMovement(const MotionEvent* event);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    // Gets the velocity of the specified pointer id in position units per second.
							 | 
						||
| 
								 | 
							
								    // Returns false and sets the velocity components to zero if there is
							 | 
						||
| 
								 | 
							
								    // insufficient movement information for the pointer.
							 | 
						||
| 
								 | 
							
								    bool getVelocity(uint32_t id, float* outVx, float* outVy) const;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    // Gets an estimator for the recent movements of the specified pointer id.
							 | 
						||
| 
								 | 
							
								    // Returns false and clears the estimator if there is no information available
							 | 
						||
| 
								 | 
							
								    // about the pointer.
							 | 
						||
| 
								 | 
							
								    bool getEstimator(uint32_t id, Estimator* outEstimator) const;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    // Gets the active pointer id, or -1 if none.
							 | 
						||
| 
								 | 
							
								    inline int32_t getActivePointerId() const { return mActivePointerId; }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    // Gets a bitset containing all pointer ids from the most recent movement.
							 | 
						||
| 
								 | 
							
								    inline BitSet32 getCurrentPointerIdBits() const { return mCurrentPointerIdBits; }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								private:
							 | 
						||
| 
								 | 
							
								    static const char* DEFAULT_STRATEGY;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    nsecs_t mLastEventTime;
							 | 
						||
| 
								 | 
							
								    BitSet32 mCurrentPointerIdBits;
							 | 
						||
| 
								 | 
							
								    int32_t mActivePointerId;
							 | 
						||
| 
								 | 
							
								    VelocityTrackerStrategy* mStrategy;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    bool configureStrategy(const char* strategy);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    static VelocityTrackerStrategy* createStrategy(const char* strategy);
							 | 
						||
| 
								 | 
							
								};
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								/*
							 | 
						||
| 
								 | 
							
								 * Implements a particular velocity tracker algorithm.
							 | 
						||
| 
								 | 
							
								 */
							 | 
						||
| 
								 | 
							
								class VelocityTrackerStrategy {
							 | 
						||
| 
								 | 
							
								protected:
							 | 
						||
| 
								 | 
							
								    VelocityTrackerStrategy() { }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								public:
							 | 
						||
| 
								 | 
							
								    virtual ~VelocityTrackerStrategy() { }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    virtual void clear() = 0;
							 | 
						||
| 
								 | 
							
								    virtual void clearPointers(BitSet32 idBits) = 0;
							 | 
						||
| 
								 | 
							
								    virtual void addMovement(nsecs_t eventTime, BitSet32 idBits,
							 | 
						||
| 
								 | 
							
								            const VelocityTracker::Position* positions) = 0;
							 | 
						||
| 
								 | 
							
								    virtual bool getEstimator(uint32_t id, VelocityTracker::Estimator* outEstimator) const = 0;
							 | 
						||
| 
								 | 
							
								};
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								/*
							 | 
						||
| 
								 | 
							
								 * Velocity tracker algorithm based on least-squares linear regression.
							 | 
						||
| 
								 | 
							
								 */
							 | 
						||
| 
								 | 
							
								class LeastSquaresVelocityTrackerStrategy : public VelocityTrackerStrategy {
							 | 
						||
| 
								 | 
							
								public:
							 | 
						||
| 
								 | 
							
								    enum Weighting {
							 | 
						||
| 
								 | 
							
								        // No weights applied.  All data points are equally reliable.
							 | 
						||
| 
								 | 
							
								        WEIGHTING_NONE,
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        // Weight by time delta.  Data points clustered together are weighted less.
							 | 
						||
| 
								 | 
							
								        WEIGHTING_DELTA,
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        // Weight such that points within a certain horizon are weighed more than those
							 | 
						||
| 
								 | 
							
								        // outside of that horizon.
							 | 
						||
| 
								 | 
							
								        WEIGHTING_CENTRAL,
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        // Weight such that points older than a certain amount are weighed less.
							 | 
						||
| 
								 | 
							
								        WEIGHTING_RECENT,
							 | 
						||
| 
								 | 
							
								    };
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    // Degree must be no greater than Estimator::MAX_DEGREE.
							 | 
						||
| 
								 | 
							
								    LeastSquaresVelocityTrackerStrategy(uint32_t degree, Weighting weighting = WEIGHTING_NONE);
							 | 
						||
| 
								 | 
							
								    virtual ~LeastSquaresVelocityTrackerStrategy();
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    virtual void clear();
							 | 
						||
| 
								 | 
							
								    virtual void clearPointers(BitSet32 idBits);
							 | 
						||
| 
								 | 
							
								    virtual void addMovement(nsecs_t eventTime, BitSet32 idBits,
							 | 
						||
| 
								 | 
							
								            const VelocityTracker::Position* positions);
							 | 
						||
| 
								 | 
							
								    virtual bool getEstimator(uint32_t id, VelocityTracker::Estimator* outEstimator) const;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								private:
							 | 
						||
| 
								 | 
							
								    // Sample horizon.
							 | 
						||
| 
								 | 
							
								    // We don't use too much history by default since we want to react to quick
							 | 
						||
| 
								 | 
							
								    // changes in direction.
							 | 
						||
| 
								 | 
							
								    static const nsecs_t HORIZON = 100 * 1000000; // 100 ms
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    // Number of samples to keep.
							 | 
						||
| 
								 | 
							
								    static const uint32_t HISTORY_SIZE = 20;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    struct Movement {
							 | 
						||
| 
								 | 
							
								        nsecs_t eventTime;
							 | 
						||
| 
								 | 
							
								        BitSet32 idBits;
							 | 
						||
| 
								 | 
							
								        VelocityTracker::Position positions[MAX_POINTERS];
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        inline const VelocityTracker::Position& getPosition(uint32_t id) const {
							 | 
						||
| 
								 | 
							
								            return positions[idBits.getIndexOfBit(id)];
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								    };
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    float chooseWeight(uint32_t index) const;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    const uint32_t mDegree;
							 | 
						||
| 
								 | 
							
								    const Weighting mWeighting;
							 | 
						||
| 
								 | 
							
								    uint32_t mIndex;
							 | 
						||
| 
								 | 
							
								    Movement mMovements[HISTORY_SIZE];
							 | 
						||
| 
								 | 
							
								};
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								/*
							 | 
						||
| 
								 | 
							
								 * Velocity tracker algorithm that uses an IIR filter.
							 | 
						||
| 
								 | 
							
								 */
							 | 
						||
| 
								 | 
							
								class IntegratingVelocityTrackerStrategy : public VelocityTrackerStrategy {
							 | 
						||
| 
								 | 
							
								public:
							 | 
						||
| 
								 | 
							
								    // Degree must be 1 or 2.
							 | 
						||
| 
								 | 
							
								    IntegratingVelocityTrackerStrategy(uint32_t degree);
							 | 
						||
| 
								 | 
							
								    ~IntegratingVelocityTrackerStrategy();
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    virtual void clear();
							 | 
						||
| 
								 | 
							
								    virtual void clearPointers(BitSet32 idBits);
							 | 
						||
| 
								 | 
							
								    virtual void addMovement(nsecs_t eventTime, BitSet32 idBits,
							 | 
						||
| 
								 | 
							
								            const VelocityTracker::Position* positions);
							 | 
						||
| 
								 | 
							
								    virtual bool getEstimator(uint32_t id, VelocityTracker::Estimator* outEstimator) const;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								private:
							 | 
						||
| 
								 | 
							
								    // Current state estimate for a particular pointer.
							 | 
						||
| 
								 | 
							
								    struct State {
							 | 
						||
| 
								 | 
							
								        nsecs_t updateTime;
							 | 
						||
| 
								 | 
							
								        uint32_t degree;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        float xpos, xvel, xaccel;
							 | 
						||
| 
								 | 
							
								        float ypos, yvel, yaccel;
							 | 
						||
| 
								 | 
							
								    };
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    const uint32_t mDegree;
							 | 
						||
| 
								 | 
							
								    BitSet32 mPointerIdBits;
							 | 
						||
| 
								 | 
							
								    State mPointerState[MAX_POINTER_ID + 1];
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    void initState(State& state, nsecs_t eventTime, float xpos, float ypos) const;
							 | 
						||
| 
								 | 
							
								    void updateState(State& state, nsecs_t eventTime, float xpos, float ypos) const;
							 | 
						||
| 
								 | 
							
								    void populateEstimator(const State& state, VelocityTracker::Estimator* outEstimator) const;
							 | 
						||
| 
								 | 
							
								};
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								/*
							 | 
						||
| 
								 | 
							
								 * Velocity tracker strategy used prior to ICS.
							 | 
						||
| 
								 | 
							
								 */
							 | 
						||
| 
								 | 
							
								class LegacyVelocityTrackerStrategy : public VelocityTrackerStrategy {
							 | 
						||
| 
								 | 
							
								public:
							 | 
						||
| 
								 | 
							
								    LegacyVelocityTrackerStrategy();
							 | 
						||
| 
								 | 
							
								    virtual ~LegacyVelocityTrackerStrategy();
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    virtual void clear();
							 | 
						||
| 
								 | 
							
								    virtual void clearPointers(BitSet32 idBits);
							 | 
						||
| 
								 | 
							
								    virtual void addMovement(nsecs_t eventTime, BitSet32 idBits,
							 | 
						||
| 
								 | 
							
								            const VelocityTracker::Position* positions);
							 | 
						||
| 
								 | 
							
								    virtual bool getEstimator(uint32_t id, VelocityTracker::Estimator* outEstimator) const;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								private:
							 | 
						||
| 
								 | 
							
								    // Oldest sample to consider when calculating the velocity.
							 | 
						||
| 
								 | 
							
								    static const nsecs_t HORIZON = 200 * 1000000; // 100 ms
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    // Number of samples to keep.
							 | 
						||
| 
								 | 
							
								    static const uint32_t HISTORY_SIZE = 20;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    // The minimum duration between samples when estimating velocity.
							 | 
						||
| 
								 | 
							
								    static const nsecs_t MIN_DURATION = 10 * 1000000; // 10 ms
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    struct Movement {
							 | 
						||
| 
								 | 
							
								        nsecs_t eventTime;
							 | 
						||
| 
								 | 
							
								        BitSet32 idBits;
							 | 
						||
| 
								 | 
							
								        VelocityTracker::Position positions[MAX_POINTERS];
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        inline const VelocityTracker::Position& getPosition(uint32_t id) const {
							 | 
						||
| 
								 | 
							
								            return positions[idBits.getIndexOfBit(id)];
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								    };
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    uint32_t mIndex;
							 | 
						||
| 
								 | 
							
								    Movement mMovements[HISTORY_SIZE];
							 | 
						||
| 
								 | 
							
								};
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								} // namespace android
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								#endif // _LIBINPUT_VELOCITY_TRACKER_H
							 |