#소개하는 내용의 일부는 Android Develop API Guides를 참고했습니다.
안녕하세요. PEACE- 에요.
안드로이드 스터디의 첫 번째 글이네요.
오늘은 내용은 ANDROID 에서 지원하는 Sensor를 알아보겠습니다.
항상 비슷할 예정이지만 포스팅 목차는 다음과 같습니다.
안드로이드 플랫폼은 3가지 범주의 센서를 지원합니다.
- 모션 센서, 환경 센서, 위치 센서
함께 알아 볼 센서는 바로 '모션 센서' 입니다.
모션 센서(Motion Sensor) 안에서도 'Software-based'와 'Hardware-based'가 있지만
'Hardware-based'에 속하는 센서를 알아보겠습니다.
본 포스팅에서는 '가속도계 센서(Accelometer Sensor)'에 대해 다루겠습니다.
우리가 이 센서들을 왜 사용하는가?
기본적으로
안드로이드에서 제공하는 Motion Sensor API를 통해 센서에서 정밀하게 측정되는 값을 추출하고
데이터를 분석할 수 있는 '모니터링'을 하기 위해서입니다.
저 역시 그렇답니다.
# 1 Simple Overview
1. 가속도계 센서는 3차원 공간에서의 방향, 움직임에 대한 값(value)을 알려줍니다.
2. 기본적으로 우리가 알고있는 X Y Z축으로 여러 계산을 하며 방향(+, -), 각도(angle)를 구할 수 있습니다.
3. 사람이 중력의 영향을 받는 것 처럼 가속도계 센서도 중력의 영향을 받습니다.
더 정확하게는 움직임에 의해 바닥과 0보다 큰 각이 만들어지는 각 축에 중력가속도의 값이 적용됩니다.
4. 가속도계 센서의 이해를 돕기위해 그림으로 간단하게 표현하겠습니다.
아래 그림은 안드로이드 폰(LG G2)를 통해 얻어낸 결과입니다.
[그림 2] 출력 값의 부호에 따른 축의 방향
[그림 3] 폰의 상태에 따른 중력 가속도 영향
[그림 3]에 보이는 폰 상태에서 각도가 조금만 틀어져도 0값을 가졌던 축의 값과 주 축의 값이 '증가' 또는 '감소'하게 된다.
결국 다음과같이 됩니다.
sqrt(X^2 + Y^2 + Z^2) = 9.8
# 그렇다면 각도는 어떻게 구할까? 그림과 함께 텍스트를 만들어 첨부했다.
한계 점 : 가속도계 센서의 가속도 성분을 통해 얻어낸 회전각이므로 가속도의 영향을 받는다.
즉, 빠른 회전이나 갑작스런 턴 상태에서 측정되는 회전각은 참 값에 벗어나는 현상이 일어난다.
이에 대한 자세한 설명과 해결 방안에 대해에서는
자이로스코프센서 포스팅 다음에 포스팅하겠습니다.
# 2 How to use?
#프로그램 소개
버튼을 누르고 있는 동안 가속도계 Sensor가 작동한다.
출력은 로그를 통해 가속도계 센서의 X Y Z값을 출력했다.
추가로 Z Y Z의 출력 값을 통해 'Z-X', 'Z-Y'사이의 각도를 계산하여 출력했다.
#실행 결과
#소스 코드
activity_main.xml
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/activity_main"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingBottom="@dimen/activity_vertical_margin"
android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin"
tools:context="peace.sensorservice2.MainActivity"
android:orientation="vertical">
<LinearLayout
android:layout_weight="1"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal">
<Button
android:id="@+id/a_start"
android:layout_weight="1"
android:text="A start"
android:layout_width="wrap_content"
android:layout_height="match_parent" />
</LinearLayout>
</LinearLayout>
import android.content.Context;
import android.hardware.Sensor;
import android.hardware.SensorEvent;
import android.hardware.SensorEventListener;
import android.hardware.SensorManager;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.util.Log;
import android.view.MotionEvent;
import android.view.View;
public class MainActivity extends AppCompatActivity {
//Using the Accelometer & Gyroscoper
private SensorManager mSensorManager = null;
//Using the Accelometer
private SensorEventListener mAccLis;
private Sensor mAccelometerSensor = null;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
//Using the Gyroscope & Accelometer
mSensorManager = (SensorManager) getSystemService(Context.SENSOR_SERVICE);
//Using the Accelometer
mAccelometerSensor = mSensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER);
mAccLis = new AccelometerListener();
//Touch Listener for Accelometer
findViewById(R.id.a_start).setOnTouchListener(new View.OnTouchListener() {
@Override
public boolean onTouch(View v, MotionEvent event) {
switch (event.getAction()){
case MotionEvent.ACTION_DOWN:
mSensorManager.registerListener(mAccLis, mAccelometerSensor, SensorManager.SENSOR_DELAY_UI);
break;
case MotionEvent.ACTION_UP:
mSensorManager.unregisterListener(mAccLis);
break;
}
return false;
}
});
}
@Override
public void onPause(){
super.onPause();
Log.e("LOG", "onPause()");
mSensorManager.unregisterListener(mAccLis);
}
@Override
public void onDestroy(){
super.onDestroy();
Log.e("LOG", "onDestroy()");
mSensorManager.unregisterListener(mAccLis);
}
private class AccelometerListener implements SensorEventListener {
@Override
public void onSensorChanged(SensorEvent event) {
double accX = event.values[0];
double accY = event.values[1];
double accZ = event.values[2];
double angleXZ = Math.atan2(accX, accZ) * 180/Math.PI;
double angleYZ = Math.atan2(accY, accZ) * 180/Math.PI;
Log.e("LOG", "ACCELOMETER [X]:" + String.format("%.4f", event.values[0])
+ " [Y]:" + String.format("%.4f", event.values[1])
+ " [Z]:" + String.format("%.4f", event.values[2])
+ " [angleXZ]: " + String.format("%.4f", angleXZ)
+ " [angleYZ]: " + String.format("%.4f", angleYZ));
}
@Override
public void onAccuracyChanged(Sensor sensor, int accuracy) {
}
}
}
댓글과 공감은 환영입니다.