@@ -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
686693IntegratingVelocityTrackerStrategy::~IntegratingVelocityTrackerStrategy () {
@@ -725,18 +732,20 @@ bool IntegratingVelocityTrackerStrategy::getEstimator(uint32_t id,
725732}
726733
727734void 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
738747void 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
765789void 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