1.問題背景
從google原生算法,可以知道其有2個比較大的缺陷:
1) 通過重力傳感器傳來的x,y,z軸的加速度合成之后只有一個垂直往下的加速度,如果此時用戶在別的方向上有加速度,那么通過反余弦、反正切等計算的角度就會不準確,原始的角度計算有問題,就談不上識別正確的方向了。而google在旋轉角度上,并未用代碼進行修正。
2) google拿到方向信息之后,去干擾采取的措施是延遲300-500ms,等徹底沒有干擾的時候再進行方向改變,這個方案很保守。由于普通用戶正常轉屏都會觸發抖動和加速(70%左右都會觸發),這樣就會導致,就算是旋轉角度計算沒有任何問題,也會由于算法導致300-500ms的延遲。
2.優化措施
1.1采集數據時,提高采樣靈敏度
? ? ? ? ?private final float?FILTER_TIME_CONSTANT_MS?= tcl.Features.has("PERF_ROTATION") ? 70.0f : 200.0f;
? ? ? ? ? ? ? ? ? ? //兩次事件間隔,單位是ms,一般默認SENSOR_DELAY_NORMAL時,gsensor上報數據是66.666ms左右
? ? ? ? ? ? ? ? ? ? final?float?timeDeltaMS = (now - then) *?0.000001f;
? ? ? ? ? ? ? ? ? ? final float alpha = timeDeltaMS / (FILTER_TIME_CONSTANT_MS?+ timeDeltaMS);
? ? ? ? ? ? ? ? ? ? x = alpha * (x - mLastFilteredX) + mLastFilteredX;
? ? ? ? ? ? ? ? ? ? y = alpha * (y - mLastFilteredY) + mLastFilteredY;
? ? ? ? ? ? ? ? ? ? z = alpha * (z - mLastFilteredZ) + mLastFilteredZ;
原生FILTER_TIME_CONSTANT_MS為200ms,alpha約為0.25,即xyz的漸變速率是0.25。TCL的漸變速率約為0.49。即TCL計算得到的角度更大,猜測會會導致方向預測更加靈敏。
1.2獲取預測角度時,提高更新頻率
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? tclWindowOrientation.updateTimestamp(orientationAngle, tiltAngle, nearestRotation, mCurrentRotation,
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? PROPOSAL_MIN_TIME_SINCE_SWING_ENDED_NANOS, PROPOSAL_MIN_TIME_SINCE_ACCELERATION_ENDED_NANOS,
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? now, mSwingTimestampNanos, mAccelerationTimestampNanos, mPredictedRotation,
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? mPredictedRotationTimestampNanos);
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? mSwingTimestampNanos = tclWindowOrientation.getSwingTimestampNanos();
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? mAccelerationTimestampNanos = tclWindowOrientation.getAccelerationTimestampNanos();
原生:擺動的更新頻率是300ms,加速度的更新頻率是500ms
?private static final long PROPOSAL_MIN_TIME_SINCE_SWING_ENDED_NANOS = 300 * NANOS_PER_MS;
? ? ? ? ? ? if (now < mSwingTimestampNanos + PROPOSAL_MIN_TIME_SINCE_SWING_ENDED_NANOS) {
? ? ? ? ? ? ? ? return false;
? ? ? ? ? ? }
?private static final long PROPOSAL_MIN_TIME_SINCE_ACCELERATION_ENDED_NANOS =? ?500 * NANOS_PER_MS;
? ? ? ? ? ? if (now < mAccelerationTimestampNanos? ?+ PROPOSAL_MIN_TIME_SINCE_ACCELERATION_ENDED_NANOS) {
? ? ? ? ? ? ? ? return false;
? ? ? ? ? ? }
TCL:擺動的更新頻率是200ms,加速度的更新頻率是400ms,減少了100ms的延遲
?long PROPOSAL_MIN_TIME_ENDED_NANOS = 100 * NANOS_PER_MS;
//簡化后
if (now < mSwingTimestampNanos + PROPOSAL_MIN_TIME_SINCE_SWING_ENDED_NANOS-PROPOSAL_MIN_TIME_ENDED_NANOS) {
? ? ? ? ? ? ? ? ? ? swingNanos = now - minTimeSinceSwing + PROPOSAL_MIN_TIME_ENDED_NANOS;
? ? ? ? ? ? ? ? ? ? accelerationNanos = now - minTimeSinceAcceleration + PROPOSAL_MIN_TIME_ENDED_NANOS;
? ? ? ? ? ? ? ? isSwingTimeChange = false;
? ? ? ? ? ? ? ? isAccelerationTimeChange = false;
1.3預測角度歸一時,提高采樣范圍
? ? ? ? private final int ADJACENT_ORIENTATION_ANGLE_GAP = tcl.Features.has("PERF_ROTATION") ? 30 : 45;
以逆時針相鄰為例??
//0-360度減去22.5度,即(0,1,2,3)-->(-22.5,67.5,157.5,247.5)
int lowerBound = rotation * 90 - 45 + ADJACENT_ORIENTATION_ANGLE_GAP / 2;
//0(豎直向上):(315,360)縮短(337.5,360)
?if (rotation == 0) { if (orientationAngle >= 315 && orientationAngle < lowerBound + 360) { return false; } }
//其他范圍邊際縮小22.5度 ,
else?{?if?(orientationAngle < lowerBound) {?return?false; } }
原生:
//0-360度減去22.5度,即(0,1,2,3)-->(-22.5,67.5,157.5,247.5)
0-->(0,45)&(337.5,360),1-->(67.5,135),2-->(157.5,225),3→(247.5,315)
TCL:多減去7.5度,擴大了采樣范圍
//0-360度減去30度,即(0,1,2,3)-->(30,60,150,250)
0→(0,45)&(330,360),1→(60,135),2→(150,225),3→(240,315)
1.4通知監聽更新時,增加加速度判斷
原生:通過重力傳感器傳來的x,y,z軸的加速度合成之后只有一個垂直往下的加速度,如果此時用戶在別的方向上有加速度,那么通過反余弦、反正切等計算的角度就會不準確,導致最終計算的方向不準。
TCL:
?final float?magnitudeData?= (float) Math.sqrt(x * x + y * y + z * z);
if (isTiltAngleAcceptableLocked(nearestRotation, tiltAngle)
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? && (isOrientationAngleAcceptableLocked(nearestRotation, orientationAngle) || (tclWindowOrientation != null && tclWindowOrientation.isRotating()))
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? && (tclWindowOrientation == null ||?magnitudeData < MAX_ACCELERATION_MAGNITUDE) ?//判斷計算的加速度小于可容忍的最大加速度
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?)?
3.方案介紹
3.1流程圖
參考原生屏幕旋轉算法(AccelSensor) - 終端OS部 - Confluence (tclking.com)?中的流程圖
3.2代碼提交
topic:JIRA-SOC15MT6835-19536 | sz.gerrit Code Review (tclcom.com)
4.調試自測
1)查看sensor類型
Goldfinch_TMO:/ # dumpsys ?window|grep Sensor
? ? ? AccelSensorJudge
2)自測用例