summaryrefslogtreecommitdiffstats
path: root/libs/androidfw/VelocityTracker.cpp
diff options
context:
space:
mode:
authorJeff Brown <jeffbrown@google.com>2012-06-03 21:19:16 -0700
committerAndroid Git Automerger <android-git-automerger@android.com>2012-06-03 21:19:16 -0700
commit767bc6d26c98594525ed7dd94e8880335e15e8a8 (patch)
tree7e5a977d8c4486530f198baec39934267cd1decb /libs/androidfw/VelocityTracker.cpp
parent7d3fa093bbd34e19f6b580b6258c8ea4e138c777 (diff)
parent1fbbc0716f9b70c6dcee00c4550757077ef7f7b5 (diff)
downloadframeworks_base-767bc6d26c98594525ed7dd94e8880335e15e8a8.zip
frameworks_base-767bc6d26c98594525ed7dd94e8880335e15e8a8.tar.gz
frameworks_base-767bc6d26c98594525ed7dd94e8880335e15e8a8.tar.bz2
am 1fbbc071: Merge "Implement an integrating VelocityTracker strategy." into jb-dev
* commit '1fbbc0716f9b70c6dcee00c4550757077ef7f7b5': Implement an integrating VelocityTracker strategy.
Diffstat (limited to 'libs/androidfw/VelocityTracker.cpp')
-rw-r--r--libs/androidfw/VelocityTracker.cpp104
1 files changed, 104 insertions, 0 deletions
diff --git a/libs/androidfw/VelocityTracker.cpp b/libs/androidfw/VelocityTracker.cpp
index 408b240..7300ea1 100644
--- a/libs/androidfw/VelocityTracker.cpp
+++ b/libs/androidfw/VelocityTracker.cpp
@@ -161,6 +161,14 @@ VelocityTrackerStrategy* VelocityTracker::createStrategy(const char* strategy) {
// of the velocity when the finger is released.
return new LeastSquaresVelocityTrackerStrategy(3);
}
+ if (!strcmp("int1", strategy)) {
+ // 1st order integrating filter. Quality: GOOD.
+ // Not as good as 'lsq2' because it cannot estimate acceleration but it is
+ // 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
+ // direction more quickly and accurately.
+ return new IntegratingVelocityTrackerStrategy();
+ }
return NULL;
}
@@ -564,4 +572,100 @@ bool LeastSquaresVelocityTrackerStrategy::getEstimator(uint32_t id,
return true;
}
+
+// --- IntegratingVelocityTrackerStrategy ---
+
+IntegratingVelocityTrackerStrategy::IntegratingVelocityTrackerStrategy() {
+}
+
+IntegratingVelocityTrackerStrategy::~IntegratingVelocityTrackerStrategy() {
+}
+
+void IntegratingVelocityTrackerStrategy::clear() {
+ mPointerIdBits.clear();
+}
+
+void IntegratingVelocityTrackerStrategy::clearPointers(BitSet32 idBits) {
+ mPointerIdBits.value &= ~idBits.value;
+}
+
+void IntegratingVelocityTrackerStrategy::addMovement(nsecs_t eventTime, BitSet32 idBits,
+ const VelocityTracker::Position* positions) {
+ uint32_t index = 0;
+ for (BitSet32 iterIdBits(idBits); !iterIdBits.isEmpty();) {
+ uint32_t id = iterIdBits.clearFirstMarkedBit();
+ State& state = mPointerState[id];
+ const VelocityTracker::Position& position = positions[index++];
+ if (mPointerIdBits.hasBit(id)) {
+ updateState(state, eventTime, position.x, position.y);
+ } else {
+ initState(state, eventTime, position.x, position.y);
+ }
+ }
+
+ mPointerIdBits = idBits;
+}
+
+bool IntegratingVelocityTrackerStrategy::getEstimator(uint32_t id,
+ VelocityTracker::Estimator* outEstimator) const {
+ outEstimator->clear();
+
+ if (mPointerIdBits.hasBit(id)) {
+ const State& state = mPointerState[id];
+ populateEstimator(state, outEstimator);
+ return true;
+ }
+
+ return false;
+}
+
+void IntegratingVelocityTrackerStrategy::initState(State& state,
+ nsecs_t eventTime, float xpos, float ypos) {
+ state.updateTime = eventTime;
+ state.first = true;
+
+ state.xpos = xpos;
+ state.xvel = 0;
+ state.ypos = ypos;
+ state.yvel = 0;
+}
+
+void IntegratingVelocityTrackerStrategy::updateState(State& state,
+ nsecs_t eventTime, float xpos, float ypos) {
+ const nsecs_t MIN_TIME_DELTA = 2 * NANOS_PER_MS;
+ const float FILTER_TIME_CONSTANT = 0.010f; // 10 milliseconds
+
+ if (eventTime <= state.updateTime + MIN_TIME_DELTA) {
+ return;
+ }
+
+ float dt = (eventTime - state.updateTime) * 0.000000001f;
+ state.updateTime = eventTime;
+
+ float xvel = (xpos - state.xpos) / dt;
+ float yvel = (ypos - state.ypos) / dt;
+ if (state.first) {
+ state.xvel = xvel;
+ state.yvel = yvel;
+ state.first = false;
+ } else {
+ float alpha = dt / (FILTER_TIME_CONSTANT + dt);
+ state.xvel += (xvel - state.xvel) * alpha;
+ state.yvel += (yvel - state.yvel) * alpha;
+ }
+ state.xpos = xpos;
+ state.ypos = ypos;
+}
+
+void IntegratingVelocityTrackerStrategy::populateEstimator(const State& state,
+ VelocityTracker::Estimator* outEstimator) {
+ outEstimator->time = state.updateTime;
+ outEstimator->degree = 1;
+ outEstimator->confidence = 1.0f;
+ outEstimator->xCoeff[0] = state.xpos;
+ outEstimator->xCoeff[1] = state.xvel;
+ outEstimator->yCoeff[0] = state.ypos;
+ outEstimator->yCoeff[1] = state.yvel;
+}
+
} // namespace android