
ãã®ãããªæ¬ãèšäºããã¹ã§èªãã ããéããæ©ãããããŸãããïŒ è©Šããã«éããªãïŒ ãã®å Žåããã®ããã«ããã¹ããèªãããšã¯çµ¶ããæºããŠããã®ã§è¯ãèãã§ã¯ãªãããšã«æ°ã¥ããã¯ãã§ãã ç»é¢ãæºããããšã¯ããªãæ·±å»ãªåé¡ã§ãããããããªããããšã¯éåžžã«è¯ãUXã®æ¹åãããããããšãã§ããããã§ãã ç§ã®ã¢ã€ãã¢ã¯ã äžçŒã¬ãã«ã¡ã©ãã»ã³ãµãŒãã¬ã³ãºãå®å®ãããããã«ãå é床ã»ã³ãµãŒã䜿çšããŠæºããè£æ£ããããšã§ãã æè¡çã«ã¯ãããã¯å¯èœã§ãã®ã§ãèªåã§ãã£ãŠã¿ãŠãã ããïŒ
æ¢åã®ãœãªã¥ãŒã·ã§ã³
ãŸããæ¢åã®ãœãªã¥ãŒã·ã§ã³ãèŠãŠã¿ãŸãããã åãããŒãã«é¢ããèå³æ·±ãèšäºããŠã§ãäžã«ããã€ããããŸãã
- NoShakeïŒ 2009幎ã«å
¬éãããiPhoneã®ç»é¢å®å®åã«é¢ããLin ZhongãAhmad Rahmatiãããã³Clayton Shepardã«ããã¢ãã€ã«ããã€ã¹ã®ç»é¢ã®æºãã«å¯Ÿããã³ã³ãã³ãã®å®å®å ïŒ3ïŒã 620 MHz ARMããã»ããµã®é»åïŒ
ã ãã®ããããã®å®è£
ã¯å®éã®äœ¿çšã«ã¯å®çšçã§ã¯ãããŸããã ãŸããææ°ã®iPhoneã¯ãã®ã¿ã¹ã¯ã«ç°¡åã«å¯ŸåŠã§ããŸãããäœæè
ã¯ãœãŒã¹ã³ãŒãããå®éã«è©Šçšã§ããããã«ã¢ã»ã³ãã«ãããã¢ããªã±ãŒã·ã§ã³ãæäŸããŠããŸããã
- ã¹ããŒããã©ã³ã§æ©ãïŒç»é¢ã³ã³ãã³ããå®å®ãããKevin Jeisyèã ãã®èšäºã¯2014幎ã«çºè¡ããããã®ã§ãæ°åŠçãªåºç€ããããŸãã ãã®èšäºã¯ããé ããã«ã³ãã¢ãã«ã䜿çšãããšãçè«çã«ã¯è¯å¥œãªå®å®åãåŸãããšçµè«ä»ããŠããŸãã æ®å¿µãªããããœãŒã¹ã³ãŒããã³ã³ãã€ã«ãããã¢ããªã±ãŒã·ã§ã³ãæäŸãããŠããªããããåäœããŸããã
- ã·ã§ã€ã¯ããªãŒã¹ã¯ãªãŒã³ ã åã質åã調æ»ãããŠããŸãããè©ŠããŠã¿ãæ¢è£œã®çµæã¯ãããŸããã
ãããã®èšäºã¯ãç§ãã¡ã®èšäºã®ãããã¯ã®è¯ã説æãæäŸããŸãããæ®å¿µãªããšã«ããœãŒã¹ã³ãŒããŸãã¯ãããã©ã€ãã§èŠãããã®ã³ã³ãã€ã«ãããã¢ããªã±ãŒã·ã§ã³ãæäŸããŸããã è»èŒªãåçºæããç¬èªã®æ¹æ³ã§ç»é¢ã®å®å®åãå®è£ ããŠã¿ãŸãããã
çè«
å é床ã»ã³ãµãŒã䜿çšããŠãããã€ã¹ã®åããå€æã§ããŸãã ããããååããå€æãããšããã®ã»ã³ãµãŒã¯ãŸã å é床ã決å®ããããã«èšèšãããŠããŸãã ãå é床ã®ããå€äœã決å®ããæ¹æ³ããšãã質åã«çããããã«ãã»ã³ãµãŒä»ãã®ããã€ã¹ãèŠãŠã¿ãŸãããã

ã芧ã®ãšããããããã3ã€ã®è»žããããã»ã³ãµãŒã¯åºåã«3ã€ã®å€ãäžããŸãã æè¡çã«ã¯ãã»ã³ãµãŒã¯ç°ãªã軞ã«ãã3ã€ã®ã»ã³ãµãŒã§æ§æãããŠããŸãããå šäœãšããŠèŠãŠã¿ãŸãããã
3ã€ã®åºåå€ã¯ã察å¿ãã軞ã«æ²¿ã£ãå é床ã瀺ããŸãã

å é床ã¯ãm / s2ãã§æž¬å®ãããŸãã ã芧ã®ãšãããY軞ã«æ²¿ã£ãŠå é床ããããŸãããå®éã«ã¯ãããéåå é床ã§ãããããã€ã¹ãå転ããããš3ã€ã®å€ããã¹ãŠå€åããŸãã

ããŒãã§ããã€ã¹ã«çµã³ä»ããããããŒã«ãšããŠæ³åã§ããŸãã ããã¯ããªãè¯ã説æã§ãããªããªããããŒã«ãç¢å°ã«çœ®ãæãããšãå éãã¯ãã«ãåŸãããããã§ãã
ããããŸããããå€äœã®å®çŸ©ã¯ã©ãã§ããïŒ
äŸã瀺ãããšã¯ã§ããŸããããããã€ã¹ãå°ãåãããšããã¯ãã«ãå€åããŸããå®éã«ã¯ã2ã€ã®ãã¯ãã«ã§æ§æãããŸãã1ïŒä»¥åã®éåãã¯ãã«ã 2ïŒå¯Ÿå¿ãã軞ã«æ²¿ã£ãåãã«ããããã€ã¹ã®å é床ãã¯ãã«ã ç§ãã¡ã«ãšã£ãŠæãèå³æ·±ãã®ã¯ããã¯ãªãŒã³ãªãå€äœãã¯ãã«ã§ãã çµæã®ãã¯ãã«ããéåã®ãã¯ãã«ãåŒãã ãã§ç°¡åã«ååŸã§ããŸãããå®éã®éåã®ãã¯ãã«ã決å®ããæ¹æ³ã¯ïŒ ãã®åé¡ã¯ããŸããŸãªæ¹æ³ã§è§£æ±ºã§ããŸããã幞ãAndroidã«ã¯ãå¿ èŠãªããšã ããè¡ãç¹å¥ãªç·åœ¢å é床ã»ã³ãµãŒããããŸãã éåžžã®ç¶æ ã§ã¯ãã»ã³ãµãŒã®åºåå€ã¯0ã§ãããããã€ã¹ãåããããšã«ãã£ãŠã®ã¿ãŒã以å€ã®å€ãååŸã§ããŸãã èå³ããããªãã ããã«ãã®ãœãŒã¹ã³ãŒãããããŸãã ããã€ã¹ã®åããå€æããããã®äžæ©ã§ãã ããã°ã©ãã³ã°ãå§ããŸãããã
å®è£
ããã€ã¹ã®åããèšç®ããæ¹æ³ãèŠã€ããããã«ã1ã€ã®ã¢ã¯ãã£ããã£ã§1ã€ã®ç°¡åãªã¢ããªã±ãŒã·ã§ã³ãéçºããŸãããã ãã®ã¢ããªã±ãŒã·ã§ã³ã¯ãå é床ã®å€åãç£èŠããããã«å¿ããŠç¹å¥ãªãã¥ãŒèŠçŽ ã移åããŸãã ãŸããã°ã©ãã«çã®å é床å€ã衚瀺ãããŸãã

ããŒã³ãŒãã®äŸã®ã¿ã瀺ããŸãã ãã¹ãŠã®ã³ãŒãã¯GITãªããžããªã«ãããŸãã éèŠãªããšã¯æ¬¡ã®ãšããã§ãã
1.移åããç¹å¥ãªèŠçŽ ã ããã¯ãã³ã³ããå ã«ããã¹ããããéããããã¯ã§ãã
<FrameLayout android:layout_width="match_parent" android:layout_height="match_parent" android:layout_above="@id/graph1" android:background="@drawable/dots_repeat_bg" android:clipChildren="false"> <LinearLayout android:id="@+id/layout_sensor" android:layout_width="match_parent" android:layout_height="match_parent" android:layout_margin="20dp" android:orientation="vertical" android:background="#5050FF"> <ImageView android:id="@+id/img_test" android:layout_width="wrap_content" android:layout_height="wrap_content" android:src="@mipmap/ic_launcher"/> <TextView android:id="@+id/txt_test" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_below="@id/img_test" android:textSize="15sp" android:text="@string/test"/> </LinearLayout> </FrameLayout>
layout_sensorã移åããã«ã¯ãã¡ãœããView.setTranslationXããã³View.setTranslationYã䜿çšããŸãã
ãŸããèŠçŽ ãã¯ãªãã¯ãããšå éšå€ã0ã«ãªã»ããããããšããã€ãã³ãã«ããµãã¹ã¯ã©ã€ãããŸããããã¯ãæåã¯éåžžã«ããããã«ãªãå¯èœæ§ãããããã§ãã
private void reset() { position[0] = position[1] = position[2] = 0; velocity[0] = velocity[1] = velocity[2] = 0; timestamp = 0; layoutSensor.setTranslationX(0); layoutSensor.setTranslationY(0); }
2.å é床ã»ã³ãµãŒã€ãã³ãããµãã¹ã¯ã©ã€ãããŸãã
sensorManager = (SensorManager) getSystemService(SENSOR_SERVICE); accelerometer = sensorManager.getDefaultSensor(Sensor.TYPE_LINEAR_ACCELERATION); sensorManager.registerListener(sensorEventListener, accelerometer, SensorManager.SENSOR_DELAY_FASTEST);
3.ãããŠæãéèŠãªããšïŒå€åã®èãæã åºæ¬çãªå®è£ ã¯æ¬¡ã®ãšããã§ãã
private final float[] velocity = new float[3]; private final float[] position = new float[3]; private long timestamp = 0; private final SensorEventListener sensorEventListener = new SensorEventListener() { @Override public void onAccuracyChanged(Sensor sensor, int accuracy) {} @Override public void onSensorChanged(SensorEvent event) { if (timestamp != 0) { float dt = (event.timestamp - timestamp) * Constants.NS2S; for(int index = 0; index < 3; ++index) { velocity[index] += event.values[index] * dt; position[index] += velocity[index] * dt * 10000; } } else { velocity[0] = velocity[1] = velocity[2] = 0f; position[0] = position[1] = position[2] = 0f; } } };
ããã§äœãèµ·ãããèŠãŠã¿ãŸãããã onSensorChangedã¡ãœããã¯ãå é床å€ãå€ãããã³ã«åŒã³åºãããŸãïŒç¿»èš³è ã®ã¡ã¢ïŒå®éã«ã¯ãã©ã®å é床å€ã«é¢ä¿ãªããã¿ã€ããŒã«ãã£ãŠåŒã³åºãããŸãïŒã æåã«è¡ãããšã¯ãã¿ã€ã ã¹ã¿ã³ãå€æ°ãåæåãããŠãããã©ããã確èªããããšã§ãã ãã®å ŽåãåçŽã«ã¡ã€ã³å€æ°ãåæåããŸãã ã¡ãœãããç¹°ãè¿ãåŒã³åºãããå Žåã次ã®åŒã䜿çšããŠèšç®ãå®è¡ããŸãã
deltaT = time() - lastTime; velocity += acceleration * deltaT; position += velocity * deltaT; lastTime = time();
ãããããå®æ°10000ã«æ°ä»ããã¯ãã§ããããçš®ã®ããžãã¯ãã³ããŒãšèããŠãã ããã
ãããŠçµæïŒ
ã芧ã®ãšãããçŸåšã®å®è£ ã«ã¯2ã€ã®åé¡ããããŸãã
- ããªããå€ãšã¯ãªãŒãå€
- ã³ã³ãããŒã«ã¯0ã«æ»ããŸãã
å®éãäž¡æ¹ã®åé¡ã®è§£æ±ºçã¯äžè¬çãªãã®ã§ã-åŒã«æå¶ãå°å ¥ããå¿ èŠããããŸãã å€æŽãããåŒã¯æ¬¡ã®ããã«ãªããŸãã
deltaT = time() - lastTime; velocity += acceleration * deltaT - VEL_FRICTION * velocity; position += velocity * deltaT - POS_FRICTION * position; lastTime = time();
ããã çŸåšã®å®è£ ã¯è¯ãããã§ãã å¹³æ»åãç¡å¹ãªå€ããã³ããã°ã©ã èšå®ã®ã«ããã®ããã®ããŒãã¹ãã£ã«ã¿ãŒãªã©ãããã€ãã®è¡šé¢çãªæ¹åãè¿œå ããŸãã
å®æããã¢ããªã±ãŒã·ã§ã³ã¯ãstandalone_appãã©ã³ãã®ãªããžããªã«ãããŸãã
Aosp
åºæ¬çãªå®å®åã¢ã«ãŽãªãºã ãéçºããç»é¢ã®å®å®åãå¯èœã§ããããšã瀺ããã¢ã¢ããªã±ãŒã·ã§ã³ãäœæããŸããã ããã§ãããã€ã¹å šäœã«äœæ¥ãé©çšã§ããŸãã ããã¯ç°¡åãªäœæ¥ã§ã¯ãããŸããããããã解決ããããšã¯ããèå³æ·±ãããšã§ãã
ãã®ã¿ã¹ã¯ãå®è¡ããã«ã¯ã AOSPã®æ§ç¯ã«é¢ããããçšåºŠã®çµéšãå¿ èŠã§ãã Googleã¯å¿ èŠãªãã¹ãŠã®ããã¥ã¡ã³ããæäŸããŸã ã éåžžã éžæãã Nexusããã€ã¹ã®AndroidãœãŒã¹ã³ãŒããããŠã³ããŒãããå¿ èŠããããŸãã Nexusã®ãã¡ãŒã ãŠã§ã¢ããã«ãããŠãã©ãã·ã¥ããŸãã çµã¿ç«ãŠãåã«ãå¿ èŠãªãã¹ãŠã®ãã©ã€ããŒãå«ããããšãå¿ããªãã§ãã ããã
ã¹ããã¯ãã¡ãŒã ãŠã§ã¢ãçµã¿ç«ãŠãããç»é¢ã®å®å®åã®éçºãšçµ±åãéå§ã§ããŸãã
å®è£ èšç»ã¯æ¬¡ã®ãšããã§ãã
- ããã€ã¹ã®ç»é¢ã移åããæ¹æ³ãèŠã€ãã
- AOSPå éšã§APIãéçºããŠãæšæºã®Androidã¢ããªã±ãŒã·ã§ã³ã§ãªãã»ãããèšå®ã§ããããã«ããŸã
- å é床ã»ã³ãµãŒããã®ããŒã¿ãåŠçãããã¢ã¢ããªã±ãŒã·ã§ã³ã§ãµãŒãã¹ãéçºããäžèšã®APIã䜿çšããŠãªãã»ãããèšå®ããŸãã ããã€ã¹ã®é»æºãå ¥ãããšãµãŒãã¹ãèªåçã«éå§ããããããé»æºãå ¥ããçŽåŸã«å®å®åãæ©èœããŸã
次ã«ããããã®åé¡ã®è§£æ±ºæ¹æ³ã説æããŸãã
1.ç 究çšã®æåã®ãã¡ã€ã«ã¯ãç»é¢èšå®ãå¶åŸ¡ããDisplayDevice.cppã§ãã èŠãã¡ãœããã¯void DisplayDevice :: setProjectionïŒint orientationãconst RectïŒnewViewportãconst RectïŒnewFrameïŒã§ãã æãèå³æ·±ãã®ã¯483è¡ç®ã§ãã

ããã§ãæçµçãªå€æãããªãã¯ã¹ã¯ä»ã®ã³ã³ããŒãã³ããã圢æãããŸãã ãããã®å€æ°ã¯ãã¹ãŠã Transformã¯ã©ã¹ã®ã€ã³ã¹ã¿ã³ã¹ã§ãã ãã®ã¯ã©ã¹ã¯ãå€æãåŠçããããã«èšèšãããŠãããããã€ãã®ãªãŒããŒããŒãæŒç®åïŒ*ãªã©ïŒããããŸãã ã·ãããè¿œå ããã«ã¯ãæ°ããèŠçŽ ãè¿œå ããŸãã

ããã€ã¹ãã³ã³ãã€ã«ããŠãã©ãã·ã¥ãããšãç»é¢ã¯æ°Žå¹³æ¹åã«å¹³è¡ç§»åXãã¯ã»ã«ãåçŽæ¹åã«å¹³è¡ç§»åYãã¯ã»ã«ç§»åããŸãã æçµçã«ãæ°ããã¡ãœããvoid setTranslateïŒint xãint yïŒãè¿œå ããå¿ èŠããããŸãã ã·ããè¡åãæ åœããŸãã
2. 2çªç®ã®èå³æ·±ããã¡ã€ã«ã¯SurfaceFlinger.cppã§ãã ãã®ãã¡ã€ã«ã¯ãç»é¢ãªãã·ã§ã³ã«ã¢ã¯ã»ã¹ããããã®APIãäœæããäžã§éèŠã§ãã æ°ããã¡ãœãããè¿œå ããã ãã§ãïŒ

ãã¹ãŠã®ãã£ã¹ãã¬ã€ã«å¯ŸããŠsetTranslateã¡ãœãããåŒã³åºããŸãã ä»ã®éšåã¯å°ãå¥åŠã«èŠããŸãããåŸã§èª¬æããŸãã ã¹ã€ããã³ã³ã¹ãã©ã¯ãã«æ°ããã»ã¯ã·ã§ã³ãè¿œå ããŠãstatus_tã¡ãœããSurfaceFlinger :: onTransactïŒuint32_tã³ãŒããconstããŒã»ã«ãšããŒã¿ãããŒã»ã«*å¿çãuint32_tãã©ã°ïŒãå€æŽããå¿ èŠããããŸãã

ãã®ã³ãŒãã¯ãæ¹åã®å ¥ãå£ã§ãã
3.ããŒã¿åŠçãµãŒãã¹ã¯éåžžã«åçŽã§ããã€ãŸãã以åã«éçºãããã¢ã«ãŽãªãºã ã䜿çšããŠãªãã»ããå€ãååŸããŸãã ããã«ããããã®å€ã¯IPCãä»ããŠSurfaceFlingerã«éä¿¡ãããŸãã

ServiceManagerã¯ãã·ã¹ãã 以å€ã®ã¢ããªã±ãŒã·ã§ã³ã§ã¯äœ¿çšã§ããªããããAndroid Studioã§èªèãããŸããã ã·ã¹ãã ã¢ããªã±ãŒã·ã§ã³ã¯ãmakefileãã«ãã·ã¹ãã ã䜿çšããŠAOSPã§ãã«ãããå¿ èŠããããŸãã ããã«ãããã¢ããªã±ãŒã·ã§ã³ã¯é衚瀺ã®Android APIã§å¿ èŠãªã¢ã¯ã»ã¹æš©ãååŸã§ããŸãã SurfaceFlingerãµãŒãã¹ã«ã¢ã¯ã»ã¹ããã«ã¯ãã¢ããªã±ãŒã·ã§ã³ã«ãandroid.permission.ACCESS_SURFACE_FLINGERãã®æš©å©ãå¿ èŠã§ãã ãããã®æš©éãæã€ããšãã§ããã®ã¯ã·ã¹ãã ã¢ããªã±ãŒã·ã§ã³ã®ã¿ã§ãïŒä»¥äžãåç §ïŒã ã³ãŒã2020ã§APIãåŒã³åºãæš©å©ãåŸãã«ã¯ãã¢ããªã±ãŒã·ã§ã³ã«ãandroid.permission.HARDWARE_TESTãã®æš©å©ãå¿ èŠã§ãã ãããã®æš©éãæã€ããšãã§ããã®ã¯ã·ã¹ãã ã¢ããªã±ãŒã·ã§ã³ã®ã¿ã§ãã ãããŠæåŸã«ãã¢ããªã±ãŒã·ã§ã³ãäœç³»çã«ããã«ã¯ã次ã®ããã«ãããã§ã¹ããå€æŽããŸãã

ãŸããé©åãªã¡ã€ã¯ãã¡ã€ã«ãäœæããŸãã

ã¢ããªã±ãŒã·ã§ã³ã®ä»ã®éšåïŒãããŒããã£ã¹ãã¬ã·ãŒããŒã®ããŠã³ããŒããèšå®ãªã©ïŒã¯ããªãæšæºçãªãã®ãªã®ã§ãããã§ã¯è§ŠããŸããã ãã®ã¢ããªã±ãŒã·ã§ã³ãäºåã«ã€ã³ã¹ããŒã«ããïŒã€ãŸãããã¡ãŒã ãŠã§ã¢ã«çž«ãä»ããïŒæ¹æ³ã瀺ãããã«æ®ã£ãŠããŸãã ãœãŒã¹ã³ãŒãã{aosp} / packages / appsãã£ã¬ã¯ããªã«é 眮ãã core.mkãã¡ã€ã«ãä¿®æ£ããŠã¢ããªã±ãŒã·ã§ã³ãå«ãŸããããã«ããŸãã

æçµãã¢ïŒ
GitHubã§è©³çŽ°æ å ±ãšãœãŒã¹ã³ãŒããèŠã€ããããšãã§ããŸãã
{aosp} / packages / appsãã£ã¬ã¯ããªã«é 眮ããå¿ èŠãããScreenStabilizationã¢ããªã±ãŒã·ã§ã³ããããŸããAOSPããããã¡ã€ã«ïŒ 0001-ScreenStabilization-application-added.patchã¯{aosp} / build ã 0001-Translate-methods-addedãã£ã¬ã¯ããªã«é©çšããå¿ èŠããããŸã.patchã¯{aosp} / frameworks / nativeãã£ã¬ã¯ããªã«é©çšããå¿ èŠããããŸãã
Nexus 2013 Mobileã®ãã¡ãŒã ãŠã§ã¢ã¯ã userdebug ãæ§æã§ã³ã³ãã€ã«ãããŠããããããã¹ãã«é©ããŠããŸãã ãã¡ãŒã ãŠã§ã¢ãã¢ããã°ã¬ãŒãããã«ã¯ããé³éãäžããããã¿ã³ãæŒããªãããé»æºããã¿ã³ãæŒããŠããŒãããŒããŒã¢ãŒãã§èµ·åããŸãã 次ã«å ¥åïŒ
fastboot -w update aosp_deb_screen_stabilization.zip
ãã®æé ã«ãããããã€ã¹äžã®ãã¹ãŠã®æ¢åããŒã¿ãåé€ãããŸãã éæšæºãã¡ãŒã ãŠã§ã¢ããã©ãã·ã¥ããã«ã¯ã次ã®ã³ãã³ãã§ããŒãããŒããŒã®ããã¯ã解é€ããå¿ èŠãããããšã«æ³šæããŠãã ããã
fastboot oem unlock
ãããã«
ãã®èšäºã§ã¯ãã·ã³ãã«ãªç»é¢å®å®åã¢ã«ãŽãªãºã ãå®è£ ããAndroidãœãŒã¹ã³ãŒããå€æŽããŠã«ã¹ã¿ã ãã¡ãŒã ãŠã§ã¢ãçµã¿ç«ãŠãããšã«ãããããã€ã¹å šäœã«é©çšããæ¹æ³ã瀺ããŸãã ãã®ã¢ã«ãŽãªãºã ã¯å®å šã§ã¯ãããŸãããããã¢ã®ç®çã«ã¯ååã§ãã Nexus 2013ã¢ãã€ã«ããã€ã¹çšã«ä¿®æ£ããããã¡ãŒã ãŠã§ã¢ãäœæããŸãããããœãŒã¹ã³ãŒãã¯ã©ã®Nexusããã€ã¹ã«ãã CyanogenModãªã©ã® AOSPã·ã¹ãã ã«ãé©çšã§ããŸããããã«ãããç»é¢ã®å®å®åãæ°ããããã€ã¹ã«çµ±åã§ããŸãã
PSå®éãç§ã¯æè¡çãªè³ªåã«çããããããã«ã blog.lemberg.co.ukã§å ¬éãããèšäºã®å ã®è±èªçã®èè ã§ããããŸãã