드론

1-13 YMFC-3D_V2 아두이노 우노 드론의 LOW PASS FILTERING 예제

coding art 2017. 9. 17. 15:21
728x90

아두이노에서  혹시 라즈베리로 넘어가실 계획인가요?

바로 이 책에서 해답을 찾으세요.

교보문고에서 절찬리에 판매중입니다.


_____________________up to here, Commercial!___________________________________________________


YMFC-3D_V2 드론 코드는 간결함 및 확실한 드론 성능으로 인해 이미 잘 알려진 오픈소스 아두이노 드론 코너이다.


 http://www.brokking.net/ymfc-3d_v2_main.html



하지만 아무리 코드가 간결하드라도 드론 비행 제어 코드에서 몇가지 습득하기 어려운 내용들이 포함되어 있으며 그 중의 하나가 바로 LOW PASS FILTERING 에 관한 것이다. 

LPF 하면 전문적인 용어이기 때문에 일반인들이 완전히 이해하기 어려운 측면이 있는 것이 사실이다. 그러므로 본 블로그에서는 알기 쉽게 LOWPASS FILTER 의 효과를 비쥬얼하게 보기 위해서 인공적인 2가지 주파수가 섞여 있는 센서 파형을 대상으로 하여 간단한 컴퓨팅 실험을 해 보기로 한다. 하나는 1Hz 파형으로 진폭을 2.0 으로 하고 다른 하나는 상대적으로 주파수가 20배 높은 즉 20Hz 수준의 고주파 파형으로서 진폭을 0.5 로 설정한다. 이와 같이 2가지 주파수가 혼합된 센서 파형을 대상으로 LPF 이 어떤 역할을 하는지 아두이노 편집기의 시리얼 플로터 기능을 사용하여 규명해 보도록 한다.



위의 setup() 코드에서는 사인파를 사용하여 2가지 주파수가 혼합된 센서 신호의 값을 계산하여 어레이 sensorV[]에 저장하고 시리얼 플로터 기능을 사용하여 출력한다.





아울러 어레이에 저장된 sensorV[]  값을 사용하여 LOW PASS FILTER에 의해 필터링 된 값을 계산하여 시리얼 플로팅 하고 앞서서 출력된 결과와 비교해 보기로 한다.

LPF 효과를 줄 수 있는 X(n) = αX(n-1) +(1-α)s(n) 형태의 recursive  디지털 LPF 공식을 사용하도록 한다. i 값을 201번부터 시작하는 것은 앞서서 출력한 센서 데이터에 연 이어서 필터링 된 신호를 출력하기 위함이다.



공개된 오픈 소스형 아두이노 드론 YMFC-3D_V2 코드에서는 α =0.7 이 사용되고 있다. 하지만 사용자는 드론 시험 비행 실시와 더불어 적절한 0.7≤ α ≤0.85 사이 값을 선택해서 사용하면 되므로 여기서는 α =0.7 과 0.85 2가지 경우만 고려하기로 한다.

파형 비교에 의하면 α 값이 0.7 이든 0.85 이든 높은 주파수에 해당하는 20HZ 파형을 잘 걸러내는 것으로 보인다. α 값이 0.85 인 경우가 더욱 깔끔하게 필터링 된 결과를 보여 준다.

실제 드론에 사용되는 자이로 센서는 주변 환경과 드론 자체로부터의 다양한 전자기적 교란이 있을 수 있으나 실제로 시각적으로 드론이 서서히 회전하거나 드론 면이 기우는 것을 보면서 조종하기 때문에 센서 신호의 주파수가 그다지 높지 않은 것이 사실이므로 이러한 간단한 기법으로 불필요한 저자기파 잡음으로 여겨지는 높은 주파수의 영향을 걸러 내도록 할 필요가 있다.





LPF_02

float pi =3.1415629543;
float freqLow = 1.0;//Hz
float freqHigh = 20.0;//Hz
float sensorV[200];
float X[200];
float alpha =0.85;

void setup() {
 Serial.begin(9600);
 X[0] = 0.0;
 for ( int i=1; i<201; i++ )   {
  sensorV[i] = 2.0*sin(2.0*pi*freqLow*i/100.0)+0.5*sin(2.0*pi*freqHigh*i/100.0);
  Serial.println(sensorV[i]);
 }

 for ( int i=201; i<401; i++ )   {
  X[i-200] =alpha*X[i-201]+(1.0-alpha)*sensorV[i-200];
  Serial.println(X[i-200]);
 }
 
}

void loop() {
}