코로나 시대에 어딜가든 QR 인증을 하고 출입 해야했는데요. 그럴때마다 카메라 또는 QR 스캔 앱을 켜서 QR 인증을 해야했습니다. QR 인증을 하는 방법은 다양했습니다. 그중 일부 앱들은 디바이스 쉐이크(흔들기)을 QR 인증 페이지로 이동 할 수 있도록 개발되었는데 이때 사용한 쉐이크 기능은 디바이스 센서를 통해서 개발되었습니다. 그렇다면 이 센서는 매번 정확한 값이 올까요? 센서 개발하다보면 간혈적으로 고주파 노이즈가 발생할 케이스가 나오는 것을 발견할 수 있는데요. 이런 고주파 노이즈에 대한 대응을 어떻게 해야할지 알아보겠습니다.
효과적인 노이즈 제거 방법
저역 필터(low-pass filter)와 고역 필터(high-pass filter)를 함께 사용하는 것은 가속도계 데이터를 안정화하고 중력의 영향을 제거하는데 매우 효과적입니다.
저역 필터 (Low-pass filter)
저역 필터는 가속도계 데이터의 노이즈를 줄이고 데이터를 부드럽게 하기 위해 사용됩니다. 저역 필터를 통해 중력 성분을 분리할 수 있습니다.
중력성분 분리하는 방법은 다음과 같습니다.
output[i]=α×input[i]+(1−α)×output[i]
input[i]
: 현재 센서 데이터 값
output[i]
: 필터링된 값
alpha (α)
: 필터 계수로, 현재 값과 이전 값의 가중치를 조정하는 역할을 합니다. α는 0과 1 사이의 값을 가집니다.
ALPHA의 역할
- alphaα 값이 클수록: 이전 값의 영향이 커집니다. 즉, 필터링된 값이 느리게 변하고, 안정적이지만 반응이 느립니다. 고주파 노이즈가 잘 제거됩니다.
- alphaα 값이 작을수록: 새로운 값의 영향이 커집니다. 즉, 필터링된 값이 빠르게 변하고, 반응이 빠르지만 노이즈가 많이 포함될 수 있습니다.
아래 코드는 저역 필터를 사용하여 중력 성분을 추출하는 예시입니다:
private static final float ALPHA = 0.8f; // 저역 필터 계수
protected float[] applyLowPassFilter(float[] input, float[] output) {
if (output == null) return input;
for (int i = 0; i < input.length; i++) {
output[i] = ALPHA * input[i] + (1 - ALPHA) * output[i];
}
return output;
}
고역 필터 (High-pass filter)
고역 필터는 저역 필터를 사용하여 분리한 중력 성분을 실제 가속도 데이터에서 제거하는 데 사용됩니다. 이를 통해 장치의 실제 가속도를 계산할 수 있습니다. 아래 코드는 저역 필터와 고역 필터를 함께 사용한 예시입니다:
@Override
public void onSensorChanged(SensorEvent event) {
if (event.sensor.getType() == Sensor.TYPE_ACCELEROMETER) {
// 저역 필터를 사용하여 중력 성분 추출
gravity = applyLowPassFilter(event.values, gravity);
// 고역 필터를 사용하여 중력 성분 제거하여 실제 가속도 계산
float x = event.values[0] - gravity[0];
float y = event.values[1] - gravity[1];
float z = event.values[2] - gravity[2];
// 추가적인 로직 수행...
}
}
정리
- 저역 필터를 사용하여 가속도계 데이터에서 중력 성분을 분리합니다.고역 필터를 사용하여 중력 성분을 제거하고 실제 가속도를 계산합니다.
이 두 가지 필터를 함께 사용함으로써 센서 데이터의 노이즈를 줄이면서 중력의 영향을 제거할 수 있습니다. 이를 통해 더욱 정확한 움직임 감지가 가능합니다.
고객들에게 이벤트 제공으로 가속도계를 활용한 흔들임을 활용해서 프로젝트에 도입하는 것을 추천 드립니다.
추가 자료
더 자세한 내용은 다음 자료를 참고하세요.