센서에 스레드를 걸어 0.5초나 1초를 sleep 시킬려는데 빨간줄이 장난 아니네요 ㅠㅠ
어디다가 스레드를 걸어야할까요 ㅠㅠ
onSensorChanged안에 스레드를 걸어 카운터를 증가시켜도 스레드가 적용안되는지
아니면 스레드는 무시하고 센서가 작동되는지 알 수 가 없네요
자바소스입니다.
public class JumpingTestActivity extends Activity implements SensorEventListener{
int count = values.Step;
private long lastTime;
//가속도 xyz를 연산하고 나온 속도를 담을 변수
private float speed;
//가속도 각각의 값을 담을 변수
private float lastX;
private float lastY;
private float lastZ;
private float x, y, z;
private static final int SHAKE_THRESHOLD = 2200;
private static final int DATA_X = SensorManager.DATA_X;
private static final int DATA_Y = SensorManager.DATA_Y;
private static final int DATA_Z = SensorManager.DATA_Z;
//여기
private SensorManager sensorManager;
private Sensor sensor;
// private Sensor sensor1;
private TextView a, b, c, d;
int jumpingcount =0;
int start=0;
int stop=0;
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
sensorManager = (SensorManager) getSystemService(Context.SENSOR_SERVICE);
sensor = sensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER);
setContentView(R.layout.main);
a = (TextView)findViewById(R.id.h);
b = (TextView)findViewById(R.id.r);
c = (TextView)findViewById(R.id.q);
d = (TextView)findViewById(R.id.w);
a.setText("onCreate");
//스타트 버턴 리스너
final Button JumpingStart = (Button) findViewById(R.id.jumpingStart);
JumpingStart.setOnClickListener(new Button.OnClickListener() {
public void onClick(View v) {
start=1;
values.Step=0;
Toast.makeText(getApplicationContext(), "서비스 시작", 1).show();
}});
//스탑 버턴 리스너
final Button JumpingStop = (Button) findViewById(R.id.jumpingStop);
JumpingStop.setOnClickListener(new Button.OnClickListener() {
public void onClick(View v) {
stop=1;
start=0;
Toast.makeText(getApplicationContext(), "서비스 종료", 1).show();
}});
}
@Override
public void onStart() {
super.onStart();
if (sensor != null)
sensorManager.registerListener(this, sensor, SensorManager.SENSOR_DELAY_GAME);
//sensorManager.registerListener(this, sensor1, SensorManager.SENSOR_DELAY_GAME);
}
@Override
public void onStop() {
super.onStop();
if (sensorManager != null)
sensorManager.unregisterListener(this);
}
@Override
protected void onDestroy() {
super.onDestroy();
if (sensorManager != null)
sensorManager.unregisterListener(this);
}
@Override
public void onAccuracyChanged(Sensor sensor, int accuracy) {
}
//센서 주요 메서드 onSensorChanged
@Override
public void onSensorChanged(SensorEvent sensorEvent) {
if(sensorEvent.sensor.getType()==Sensor.TYPE_ACCELEROMETER){
long currentTime = System.currentTimeMillis();
long gabOfTime = (currentTime - lastTime);
if(start==1){
if (gabOfTime > 200) {
lastTime = currentTime;
x = sensorEvent.values[SensorManager.DATA_X];
y = sensorEvent.values[SensorManager.DATA_Y];
z = sensorEvent.values[SensorManager.DATA_Z];
speed = Math.abs(x + y + z - lastX - lastY - lastZ) / gabOfTime * 10000;
if (speed > SHAKE_THRESHOLD) {
Log.e("Step!", "SHAKE");
values.Step = count++;
}
lastX = sensorEvent.values[DATA_X];
lastY = sensorEvent.values[DATA_Y];
lastZ = sensorEvent.values[DATA_Z];
}
}else if(stop==1){
start=0;
count=0;
stop=0;
}
a.setText("점핑한 갯수는 몇개?: "+ values.Step);
b.setText("\n\n\n가속도 센서 값 : "+ "X : "+ lastX+ "\nY : " + lastY+ "\nZ : " + lastZ);
c.setText("\n현재시간 : "+currentTime);
d.setText("\n시간차 : "+gabOfTime);
으음;;; 행위인식에서 센싱 값을 읽어들이는 스레드를 슬립시키는것...
게다가 그 주기를 임의로 한다는 것은 매우 위험한 발상입니다.
사용자의 행동(줄넘기의 주기)를 가정하는게 되니깐요...
sensor 값을 읽어들이는 스레드는 계속 실행되고 있어야 합니다.(sleep 없이)
쭈욱~ 들어오는 데이터를 시간으로 끊지 말고
frequency에 맞춰서 데이터 갯수를 지정해서 끊어 보세요
예를 들어 초당 512개의 가속도 값이 입력으로 발생되어 쌓인다고 치면
256개가 쌓였을 때...마다...
해당 값을 기준으로 상관이나 평균을 계산해서 현재 즉 최근 0.5초간 이 사람이
줄을 넘었냐 안넘었냐를 threshold 값을 기준으로 판단하는 방식이 되겠죠...
기본적인 행위 인식 시스템의 구동 시나리오입니다.
이때 센싱 데이터를 어떤 식으로 파싱하느냐는 알고리즘 별로 분류 되는거구요
화이팅~




쓰레드를 쓰는것이 아니라, onSensorChanged 호출을 받을 때마다, 시간을 체크해서, 일정 gap 이 지나지 않았으면 그냥 return 시키는 방법이 좋겠네요.