Skip to content

Commit a5b0698

Browse files
author
Jeff Brown
committed
Implement a second order integrating VT strategy.
Bug: 6413587 Change-Id: I51bc7b8cbff22b10b728fc84ee15370e9984dd55
1 parent 18f329e commit a5b0698

File tree

2 files changed

+46
-18
lines changed

2 files changed

+46
-18
lines changed

include/androidfw/VelocityTracker.h

Lines changed: 9 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -196,7 +196,8 @@ class LeastSquaresVelocityTrackerStrategy : public VelocityTrackerStrategy {
196196
*/
197197
class IntegratingVelocityTrackerStrategy : public VelocityTrackerStrategy {
198198
public:
199-
IntegratingVelocityTrackerStrategy();
199+
// Degree must be 1 or 2.
200+
IntegratingVelocityTrackerStrategy(uint32_t degree);
200201
~IntegratingVelocityTrackerStrategy();
201202

202203
virtual void clear();
@@ -209,18 +210,19 @@ class IntegratingVelocityTrackerStrategy : public VelocityTrackerStrategy {
209210
// Current state estimate for a particular pointer.
210211
struct State {
211212
nsecs_t updateTime;
212-
bool first;
213+
uint32_t degree;
213214

214-
float xpos, xvel;
215-
float ypos, yvel;
215+
float xpos, xvel, xaccel;
216+
float ypos, yvel, yaccel;
216217
};
217218

219+
const uint32_t mDegree;
218220
BitSet32 mPointerIdBits;
219221
State mPointerState[MAX_POINTER_ID + 1];
220222

221-
static void initState(State& state, nsecs_t eventTime, float xpos, float ypos);
222-
static void updateState(State& state, nsecs_t eventTime, float xpos, float ypos);
223-
static void populateEstimator(const State& state, VelocityTracker::Estimator* outEstimator);
223+
void initState(State& state, nsecs_t eventTime, float xpos, float ypos) const;
224+
void updateState(State& state, nsecs_t eventTime, float xpos, float ypos) const;
225+
void populateEstimator(const State& state, VelocityTracker::Estimator* outEstimator) const;
224226
};
225227

226228
} // namespace android

libs/androidfw/VelocityTracker.cpp

Lines changed: 37 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -182,7 +182,13 @@ VelocityTrackerStrategy* VelocityTracker::createStrategy(const char* strategy) {
182182
// more tolerant of errors. Like 'lsq1', this strategy tends to underestimate
183183
// the velocity of a fling but this strategy tends to respond to changes in
184184
// direction more quickly and accurately.
185-
return new IntegratingVelocityTrackerStrategy();
185+
return new IntegratingVelocityTrackerStrategy(1);
186+
}
187+
if (!strcmp("int2", strategy)) {
188+
// 2nd order integrating filter. Quality: EXPERIMENTAL.
189+
// For comparison purposes only. Unlike 'int1' this strategy can compensate
190+
// for acceleration but it typically overestimates the effect.
191+
return new IntegratingVelocityTrackerStrategy(2);
186192
}
187193
return NULL;
188194
}
@@ -680,7 +686,8 @@ float LeastSquaresVelocityTrackerStrategy::chooseWeight(uint32_t index) const {
680686

681687
// --- IntegratingVelocityTrackerStrategy ---
682688

683-
IntegratingVelocityTrackerStrategy::IntegratingVelocityTrackerStrategy() {
689+
IntegratingVelocityTrackerStrategy::IntegratingVelocityTrackerStrategy(uint32_t degree) :
690+
mDegree(degree) {
684691
}
685692

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

727734
void IntegratingVelocityTrackerStrategy::initState(State& state,
728-
nsecs_t eventTime, float xpos, float ypos) {
735+
nsecs_t eventTime, float xpos, float ypos) const {
729736
state.updateTime = eventTime;
730-
state.first = true;
737+
state.degree = 0;
731738

732739
state.xpos = xpos;
733740
state.xvel = 0;
741+
state.xaccel = 0;
734742
state.ypos = ypos;
735743
state.yvel = 0;
744+
state.yaccel = 0;
736745
}
737746

738747
void IntegratingVelocityTrackerStrategy::updateState(State& state,
739-
nsecs_t eventTime, float xpos, float ypos) {
748+
nsecs_t eventTime, float xpos, float ypos) const {
740749
const nsecs_t MIN_TIME_DELTA = 2 * NANOS_PER_MS;
741750
const float FILTER_TIME_CONSTANT = 0.010f; // 10 milliseconds
742751

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

750759
float xvel = (xpos - state.xpos) / dt;
751760
float yvel = (ypos - state.ypos) / dt;
752-
if (state.first) {
761+
if (state.degree == 0) {
753762
state.xvel = xvel;
754763
state.yvel = yvel;
755-
state.first = false;
764+
state.degree = 1;
756765
} else {
757766
float alpha = dt / (FILTER_TIME_CONSTANT + dt);
758-
state.xvel += (xvel - state.xvel) * alpha;
759-
state.yvel += (yvel - state.yvel) * alpha;
767+
if (mDegree == 1) {
768+
state.xvel += (xvel - state.xvel) * alpha;
769+
state.yvel += (yvel - state.yvel) * alpha;
770+
} else {
771+
float xaccel = (xvel - state.xvel) / dt;
772+
float yaccel = (yvel - state.yvel) / dt;
773+
if (state.degree == 1) {
774+
state.xaccel = xaccel;
775+
state.yaccel = yaccel;
776+
state.degree = 2;
777+
} else {
778+
state.xaccel += (xaccel - state.xaccel) * alpha;
779+
state.yaccel += (yaccel - state.yaccel) * alpha;
780+
}
781+
state.xvel += (state.xaccel * dt) * alpha;
782+
state.yvel += (state.yaccel * dt) * alpha;
783+
}
760784
}
761785
state.xpos = xpos;
762786
state.ypos = ypos;
763787
}
764788

765789
void IntegratingVelocityTrackerStrategy::populateEstimator(const State& state,
766-
VelocityTracker::Estimator* outEstimator) {
790+
VelocityTracker::Estimator* outEstimator) const {
767791
outEstimator->time = state.updateTime;
768-
outEstimator->degree = 1;
769792
outEstimator->confidence = 1.0f;
793+
outEstimator->degree = state.degree;
770794
outEstimator->xCoeff[0] = state.xpos;
771795
outEstimator->xCoeff[1] = state.xvel;
796+
outEstimator->xCoeff[2] = state.xaccel / 2;
772797
outEstimator->yCoeff[0] = state.ypos;
773798
outEstimator->yCoeff[1] = state.yvel;
799+
outEstimator->yCoeff[2] = state.yaccel / 2;
774800
}
775801

776802
} // namespace android

0 commit comments

Comments
 (0)