VelocityTracker.h revision 85bd0d62830a098c1bdc720dfdcf4fe1b18b657c
1/* 2 * Copyright (C) 2012 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17#ifndef _ANDROIDFW_VELOCITY_TRACKER_H 18#define _ANDROIDFW_VELOCITY_TRACKER_H 19 20#include <androidfw/Input.h> 21#include <utils/Timers.h> 22#include <utils/BitSet.h> 23 24namespace android { 25 26class VelocityTrackerStrategy; 27 28/* 29 * Calculates the velocity of pointer movements over time. 30 */ 31class VelocityTracker { 32public: 33 struct Position { 34 float x, y; 35 }; 36 37 struct Estimator { 38 static const size_t MAX_DEGREE = 2; 39 40 // Polynomial coefficients describing motion in X and Y. 41 float xCoeff[MAX_DEGREE + 1], yCoeff[MAX_DEGREE + 1]; 42 43 // Polynomial degree (number of coefficients), or zero if no information is 44 // available. 45 uint32_t degree; 46 47 // Confidence (coefficient of determination), between 0 (no fit) and 1 (perfect fit). 48 float confidence; 49 50 inline void clear() { 51 degree = 0; 52 confidence = 0; 53 for (size_t i = 0; i <= MAX_DEGREE; i++) { 54 xCoeff[i] = 0; 55 yCoeff[i] = 0; 56 } 57 } 58 }; 59 60 VelocityTracker(); 61 VelocityTracker(VelocityTrackerStrategy* strategy); 62 ~VelocityTracker(); 63 64 // Resets the velocity tracker state. 65 void clear(); 66 67 // Resets the velocity tracker state for specific pointers. 68 // Call this method when some pointers have changed and may be reusing 69 // an id that was assigned to a different pointer earlier. 70 void clearPointers(BitSet32 idBits); 71 72 // Adds movement information for a set of pointers. 73 // The idBits bitfield specifies the pointer ids of the pointers whose positions 74 // are included in the movement. 75 // The positions array contains position information for each pointer in order by 76 // increasing id. Its size should be equal to the number of one bits in idBits. 77 void addMovement(nsecs_t eventTime, BitSet32 idBits, const Position* positions); 78 79 // Adds movement information for all pointers in a MotionEvent, including historical samples. 80 void addMovement(const MotionEvent* event); 81 82 // Gets the velocity of the specified pointer id in position units per second. 83 // Returns false and sets the velocity components to zero if there is 84 // insufficient movement information for the pointer. 85 bool getVelocity(uint32_t id, float* outVx, float* outVy) const; 86 87 // Gets an estimator for the recent movements of the specified pointer id. 88 // Returns false and clears the estimator if there is no information available 89 // about the pointer. 90 bool getEstimator(uint32_t id, Estimator* outEstimator) const; 91 92 // Gets the active pointer id, or -1 if none. 93 inline int32_t getActivePointerId() const { return mActivePointerId; } 94 95 // Gets a bitset containing all pointer ids from the most recent movement. 96 inline BitSet32 getCurrentPointerIdBits() const { return mCurrentPointerIdBits; } 97 98private: 99 BitSet32 mCurrentPointerIdBits; 100 int32_t mActivePointerId; 101 VelocityTrackerStrategy* mStrategy; 102}; 103 104 105/* 106 * Implements a particular velocity tracker algorithm. 107 */ 108class VelocityTrackerStrategy { 109protected: 110 VelocityTrackerStrategy() { } 111 112public: 113 virtual ~VelocityTrackerStrategy() { } 114 115 virtual void clear() = 0; 116 virtual void clearPointers(BitSet32 idBits) = 0; 117 virtual void addMovement(nsecs_t eventTime, BitSet32 idBits, 118 const VelocityTracker::Position* positions) = 0; 119 virtual bool getEstimator(uint32_t id, VelocityTracker::Estimator* outEstimator) const = 0; 120}; 121 122 123/* 124 * Velocity tracker algorithm based on least-squares linear regression. 125 */ 126class LeastSquaresVelocityTrackerStrategy : public VelocityTrackerStrategy { 127public: 128 LeastSquaresVelocityTrackerStrategy(); 129 virtual ~LeastSquaresVelocityTrackerStrategy(); 130 131 virtual void clear(); 132 virtual void clearPointers(BitSet32 idBits); 133 virtual void addMovement(nsecs_t eventTime, BitSet32 idBits, 134 const VelocityTracker::Position* positions); 135 virtual bool getEstimator(uint32_t id, VelocityTracker::Estimator* outEstimator) const; 136 137private: 138 // Polynomial degree. Must be less than or equal to Estimator::MAX_DEGREE. 139 static const uint32_t DEGREE = 2; 140 141 // Sample horizon. 142 // We don't use too much history by default since we want to react to quick 143 // changes in direction. 144 static const nsecs_t HORIZON = 100 * 1000000; // 100 ms 145 146 // Number of samples to keep. 147 static const uint32_t HISTORY_SIZE = 20; 148 149 struct Movement { 150 nsecs_t eventTime; 151 BitSet32 idBits; 152 VelocityTracker::Position positions[MAX_POINTERS]; 153 154 inline const VelocityTracker::Position& getPosition(uint32_t id) const { 155 return positions[idBits.getIndexOfBit(id)]; 156 } 157 }; 158 159 uint32_t mIndex; 160 Movement mMovements[HISTORY_SIZE]; 161}; 162 163} // namespace android 164 165#endif // _ANDROIDFW_VELOCITY_TRACKER_H 166