18a90e6e3174083f274538567d851f98478fc83e9Jeff Brown/* 28a90e6e3174083f274538567d851f98478fc83e9Jeff Brown * Copyright (C) 2012 The Android Open Source Project 38a90e6e3174083f274538567d851f98478fc83e9Jeff Brown * 48a90e6e3174083f274538567d851f98478fc83e9Jeff Brown * Licensed under the Apache License, Version 2.0 (the "License"); 58a90e6e3174083f274538567d851f98478fc83e9Jeff Brown * you may not use this file except in compliance with the License. 68a90e6e3174083f274538567d851f98478fc83e9Jeff Brown * You may obtain a copy of the License at 78a90e6e3174083f274538567d851f98478fc83e9Jeff Brown * 88a90e6e3174083f274538567d851f98478fc83e9Jeff Brown * http://www.apache.org/licenses/LICENSE-2.0 98a90e6e3174083f274538567d851f98478fc83e9Jeff Brown * 108a90e6e3174083f274538567d851f98478fc83e9Jeff Brown * Unless required by applicable law or agreed to in writing, software 118a90e6e3174083f274538567d851f98478fc83e9Jeff Brown * distributed under the License is distributed on an "AS IS" BASIS, 128a90e6e3174083f274538567d851f98478fc83e9Jeff Brown * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 138a90e6e3174083f274538567d851f98478fc83e9Jeff Brown * See the License for the specific language governing permissions and 148a90e6e3174083f274538567d851f98478fc83e9Jeff Brown * limitations under the License. 158a90e6e3174083f274538567d851f98478fc83e9Jeff Brown */ 168a90e6e3174083f274538567d851f98478fc83e9Jeff Brown 178a90e6e3174083f274538567d851f98478fc83e9Jeff Brown#define LOG_TAG "VelocityControl" 188a90e6e3174083f274538567d851f98478fc83e9Jeff Brown//#define LOG_NDEBUG 0 198a90e6e3174083f274538567d851f98478fc83e9Jeff Brown 208a90e6e3174083f274538567d851f98478fc83e9Jeff Brown// Log debug messages about acceleration. 218a90e6e3174083f274538567d851f98478fc83e9Jeff Brown#define DEBUG_ACCELERATION 0 228a90e6e3174083f274538567d851f98478fc83e9Jeff Brown 238a90e6e3174083f274538567d851f98478fc83e9Jeff Brown#include <math.h> 248a90e6e3174083f274538567d851f98478fc83e9Jeff Brown#include <limits.h> 258a90e6e3174083f274538567d851f98478fc83e9Jeff Brown 268a90e6e3174083f274538567d851f98478fc83e9Jeff Brown#include <androidfw/VelocityControl.h> 278a90e6e3174083f274538567d851f98478fc83e9Jeff Brown#include <utils/BitSet.h> 288a90e6e3174083f274538567d851f98478fc83e9Jeff Brown#include <utils/Timers.h> 298a90e6e3174083f274538567d851f98478fc83e9Jeff Brown 308a90e6e3174083f274538567d851f98478fc83e9Jeff Brownnamespace android { 318a90e6e3174083f274538567d851f98478fc83e9Jeff Brown 328a90e6e3174083f274538567d851f98478fc83e9Jeff Brown// --- VelocityControl --- 338a90e6e3174083f274538567d851f98478fc83e9Jeff Brown 348a90e6e3174083f274538567d851f98478fc83e9Jeff Brownconst nsecs_t VelocityControl::STOP_TIME; 358a90e6e3174083f274538567d851f98478fc83e9Jeff Brown 368a90e6e3174083f274538567d851f98478fc83e9Jeff BrownVelocityControl::VelocityControl() { 378a90e6e3174083f274538567d851f98478fc83e9Jeff Brown reset(); 388a90e6e3174083f274538567d851f98478fc83e9Jeff Brown} 398a90e6e3174083f274538567d851f98478fc83e9Jeff Brown 408a90e6e3174083f274538567d851f98478fc83e9Jeff Brownvoid VelocityControl::setParameters(const VelocityControlParameters& parameters) { 418a90e6e3174083f274538567d851f98478fc83e9Jeff Brown mParameters = parameters; 428a90e6e3174083f274538567d851f98478fc83e9Jeff Brown reset(); 438a90e6e3174083f274538567d851f98478fc83e9Jeff Brown} 448a90e6e3174083f274538567d851f98478fc83e9Jeff Brown 458a90e6e3174083f274538567d851f98478fc83e9Jeff Brownvoid VelocityControl::reset() { 468a90e6e3174083f274538567d851f98478fc83e9Jeff Brown mLastMovementTime = LLONG_MIN; 478a90e6e3174083f274538567d851f98478fc83e9Jeff Brown mRawPosition.x = 0; 488a90e6e3174083f274538567d851f98478fc83e9Jeff Brown mRawPosition.y = 0; 498a90e6e3174083f274538567d851f98478fc83e9Jeff Brown mVelocityTracker.clear(); 508a90e6e3174083f274538567d851f98478fc83e9Jeff Brown} 518a90e6e3174083f274538567d851f98478fc83e9Jeff Brown 528a90e6e3174083f274538567d851f98478fc83e9Jeff Brownvoid VelocityControl::move(nsecs_t eventTime, float* deltaX, float* deltaY) { 538a90e6e3174083f274538567d851f98478fc83e9Jeff Brown if ((deltaX && *deltaX) || (deltaY && *deltaY)) { 548a90e6e3174083f274538567d851f98478fc83e9Jeff Brown if (eventTime >= mLastMovementTime + STOP_TIME) { 558a90e6e3174083f274538567d851f98478fc83e9Jeff Brown#if DEBUG_ACCELERATION 568a90e6e3174083f274538567d851f98478fc83e9Jeff Brown ALOGD("VelocityControl: stopped, last movement was %0.3fms ago", 578a90e6e3174083f274538567d851f98478fc83e9Jeff Brown (eventTime - mLastMovementTime) * 0.000001f); 588a90e6e3174083f274538567d851f98478fc83e9Jeff Brown#endif 598a90e6e3174083f274538567d851f98478fc83e9Jeff Brown reset(); 608a90e6e3174083f274538567d851f98478fc83e9Jeff Brown } 618a90e6e3174083f274538567d851f98478fc83e9Jeff Brown 628a90e6e3174083f274538567d851f98478fc83e9Jeff Brown mLastMovementTime = eventTime; 638a90e6e3174083f274538567d851f98478fc83e9Jeff Brown if (deltaX) { 648a90e6e3174083f274538567d851f98478fc83e9Jeff Brown mRawPosition.x += *deltaX; 658a90e6e3174083f274538567d851f98478fc83e9Jeff Brown } 668a90e6e3174083f274538567d851f98478fc83e9Jeff Brown if (deltaY) { 678a90e6e3174083f274538567d851f98478fc83e9Jeff Brown mRawPosition.y += *deltaY; 688a90e6e3174083f274538567d851f98478fc83e9Jeff Brown } 698a90e6e3174083f274538567d851f98478fc83e9Jeff Brown mVelocityTracker.addMovement(eventTime, BitSet32(BitSet32::valueForBit(0)), &mRawPosition); 708a90e6e3174083f274538567d851f98478fc83e9Jeff Brown 718a90e6e3174083f274538567d851f98478fc83e9Jeff Brown float vx, vy; 728a90e6e3174083f274538567d851f98478fc83e9Jeff Brown float scale = mParameters.scale; 738a90e6e3174083f274538567d851f98478fc83e9Jeff Brown if (mVelocityTracker.getVelocity(0, &vx, &vy)) { 748a90e6e3174083f274538567d851f98478fc83e9Jeff Brown float speed = hypotf(vx, vy) * scale; 758a90e6e3174083f274538567d851f98478fc83e9Jeff Brown if (speed >= mParameters.highThreshold) { 768a90e6e3174083f274538567d851f98478fc83e9Jeff Brown // Apply full acceleration above the high speed threshold. 778a90e6e3174083f274538567d851f98478fc83e9Jeff Brown scale *= mParameters.acceleration; 788a90e6e3174083f274538567d851f98478fc83e9Jeff Brown } else if (speed > mParameters.lowThreshold) { 798a90e6e3174083f274538567d851f98478fc83e9Jeff Brown // Linearly interpolate the acceleration to apply between the low and high 808a90e6e3174083f274538567d851f98478fc83e9Jeff Brown // speed thresholds. 818a90e6e3174083f274538567d851f98478fc83e9Jeff Brown scale *= 1 + (speed - mParameters.lowThreshold) 828a90e6e3174083f274538567d851f98478fc83e9Jeff Brown / (mParameters.highThreshold - mParameters.lowThreshold) 838a90e6e3174083f274538567d851f98478fc83e9Jeff Brown * (mParameters.acceleration - 1); 848a90e6e3174083f274538567d851f98478fc83e9Jeff Brown } 858a90e6e3174083f274538567d851f98478fc83e9Jeff Brown 868a90e6e3174083f274538567d851f98478fc83e9Jeff Brown#if DEBUG_ACCELERATION 878a90e6e3174083f274538567d851f98478fc83e9Jeff Brown ALOGD("VelocityControl(%0.3f, %0.3f, %0.3f, %0.3f): " 888a90e6e3174083f274538567d851f98478fc83e9Jeff Brown "vx=%0.3f, vy=%0.3f, speed=%0.3f, accel=%0.3f", 898a90e6e3174083f274538567d851f98478fc83e9Jeff Brown mParameters.scale, mParameters.lowThreshold, mParameters.highThreshold, 908a90e6e3174083f274538567d851f98478fc83e9Jeff Brown mParameters.acceleration, 918a90e6e3174083f274538567d851f98478fc83e9Jeff Brown vx, vy, speed, scale / mParameters.scale); 928a90e6e3174083f274538567d851f98478fc83e9Jeff Brown#endif 938a90e6e3174083f274538567d851f98478fc83e9Jeff Brown } else { 948a90e6e3174083f274538567d851f98478fc83e9Jeff Brown#if DEBUG_ACCELERATION 958a90e6e3174083f274538567d851f98478fc83e9Jeff Brown ALOGD("VelocityControl(%0.3f, %0.3f, %0.3f, %0.3f): unknown velocity", 968a90e6e3174083f274538567d851f98478fc83e9Jeff Brown mParameters.scale, mParameters.lowThreshold, mParameters.highThreshold, 978a90e6e3174083f274538567d851f98478fc83e9Jeff Brown mParameters.acceleration); 988a90e6e3174083f274538567d851f98478fc83e9Jeff Brown#endif 998a90e6e3174083f274538567d851f98478fc83e9Jeff Brown } 1008a90e6e3174083f274538567d851f98478fc83e9Jeff Brown 1018a90e6e3174083f274538567d851f98478fc83e9Jeff Brown if (deltaX) { 1028a90e6e3174083f274538567d851f98478fc83e9Jeff Brown *deltaX *= scale; 1038a90e6e3174083f274538567d851f98478fc83e9Jeff Brown } 1048a90e6e3174083f274538567d851f98478fc83e9Jeff Brown if (deltaY) { 1058a90e6e3174083f274538567d851f98478fc83e9Jeff Brown *deltaY *= scale; 1068a90e6e3174083f274538567d851f98478fc83e9Jeff Brown } 1078a90e6e3174083f274538567d851f98478fc83e9Jeff Brown } 1088a90e6e3174083f274538567d851f98478fc83e9Jeff Brown} 1098a90e6e3174083f274538567d851f98478fc83e9Jeff Brown 1108a90e6e3174083f274538567d851f98478fc83e9Jeff Brown} // namespace android 111