Quadrotor20132013. 9. 29. 19:31

(내용을 보완한 글을 새로 올렸습니다~! 하단부 알림글을 먼저 읽어보시기 바랍니다~!)


오늘은 상보필터(complementary filter)또는 보상필터라고 하는 센서 융합방법에 대해 포스팅 하겠습니다~


이전 포스팅에서는 칼만필터로 융합했었는데 수박 겉햝기식이라 내부 구조를 변경하고 이해하기엔 좀 힘들었는데 요 방법은 좀 더 직관적이고 이해하기 쉬워서 제가 맘대로 조절하기도 편하더라고요


왜 다시 융합으로 돌아왔느냐~ 하면요 ㅠ roll, pitch, yaw를 센서가 알아서 계산해서 제공해주는 값을 사용했는데 그게 update rate(샘플링타임)가 100Hz였습니다. 근데 쿼드콥터 네이버 카페에 쌍둥아빠이기성이라는 분이 댓글을 달아주셨는데 최소 200Hz는 되어야 뜬다고 하더라구요.. 전 그것도 모르고 왜안되나~ 삽질만하고.. 오히려 50Hz로 낮춰보기까지.. ㅠ 제 센서가 100Hz인데 더 높일수가 없어서 다시 mpu6050으로 돌아왔습니다. 


mpu6050의 update rate는 가속도, 자이로 각각 4~1000Hz, 4~8000Hz인데 왜 범위냐면 내부의 LPF(Low Pass Filter)를 사용할 여지가 있기 때문인거 같습니다.


아무튼, 더 빠른 센서가 필요해서 MPU6050으로 돌아왔는데, 예전 칼만필터 소스를 아두이노에서 돌리려니까 한 루프에 10ms가 넘더라구요..;;


그래서 다른 필터를 찾다가 상보 필터가 있길래 공부해서 적용시켜봤습니다.


상보 - [명사] 서로 모자란 부분을 보충함. - 네이버 사전


두 센서의 서로 모자란 부분을 보충해서 더 좋은 결과를 만들어내는게 상보 필터입니다.


가속도 센서와 자이로 센서에 대해서는 이전 포스팅을 참고해주세요. -  mpu6050 가속도, 자이로 센서를 융합하기[상보필터] - 1 



이 블록선도를 구현할 건데요. 


먼저, 가속도 센서값을 roll, pitch로 바꿔야 합니다.


바꾸는 수식은 되게 많은데.. 제가 사용한 방법은 아래과 같습니다.



xAngle이 roll이 됩니다. 마찬가지로 pitch도 구할 수 있는데 yValue대신 xValue를 사용하면 되겠죠?


스케일링을 안하는 이유는 어차피 약분될거기 때문입니다. 


다음으로는 자이로 센서를 roll, pitch로 바꿔보겠습니다.


mpu6050은 가속도 자이로 모두 -90도~90도의 값을 -16383~16383로 주기 때문에 스케일링을 해야합니다.  -> (오류 : 하단참고)


 -> (오류 : 하단참고)


참 쉽죠? ㅋ


이걸 dt(시간변화량)으로 곱해서 누적시키면 각도가 나오게 됩니다. 적분하는거죠.



그럼 이제 가속도와 자이로센서 각각의 각도를 구했습니다. mpu6050 가속도, 자이로 센서를 융합하기[상보필터] - 1 제 포스팅에 있는 그래프처럼 서로의 장단점을 보완해 봅시다.




자이로 값이 기준이 됩니다. 가속도 값이 보정값이 되는거구요. 


간단하게 말하면 자이로 값과 가속도센서의 오차를 누적시키고 누적된 오차를 자이로센서값에 더해서 가속도센서값에 근접시키는 겁니다.


다만 얼마나 빠르게 근접시키느냐에 PI제어를 추가한 거라고 보시면 되겠습니다. P게인 I게인 값을 조절하는데, 가속도 값에 빠르게 근접시키면 노이즈까지 따라갈테고 느리게 근접시키면 노이즈는 무시되겠지만 반응이 느려지는 관계를 잘 절충해서 조절해야합니다.


PID제어에 관한 개념도 제 블로그에 있으니 참고바랍니다. - 쿼드콥터 PID제어


식으로 표현하면 



입니다. 이해하기 쉽게 써볼라고 길게 늘려봤는데 이게 수학적 문법에 맞는 식인지 모르겠네요..ㄷㄷ 


식 그대로네요.. 여기에 글로 해설해 봤자 식을 읽는거에 불과하니 괄호 하나하나 이해하면서 해석해보시기 바랍니다.


High Pass Filter와 Low Pass Filter식을 유도하는거는 pinkwink님의 블로그를 참고하시기 바랍니다. - http://pinkwink.kr/78


아두이노에 사용한 소스 코드도 올리니까 한줄 한줄 이해해 보시기 바랍니다.


double x_angle = -atan((double)ay/(double)az)*180.0 / 3.1416; // 가속도 센서 각도 구하기

integral_gx += (-gx/16383.0*90.0) * dt; // 자이로 값 적분해서 자이로센서 각도 저장

cf_err_x = cf_result_x - x_angle; // 전 값과 에러 도출 // P 제어에 사용

cf_err_sum_x += cf_err_x * dt; // 에러를 적분해서 저장 // I 제어에 사용

cf_kp_val_x = cf_err_x * CF_KP;            // P value

cf_ki_val_x = cf_err_sum_x * CF_KI;        // I value

cf_pid_out_x = (-gx/16383.0*90.0) - (cf_kp_val_x + cf_ki_val_x + cf_kd_val_x); // 자이로 각도값을 PID제어를 통해 얼마나 빠르게 가속도 각도값에 맞출 것인지 결정

cf_result_x += cf_pid_out_x * dt; // 상보필터 결과를 저장 // 자이로값이므로 적분으로저장

코드 -> (오류 : 하단참고)

결과는,



이렇습니다. 빨간색이 가속도, 초록색이 자이로, 파란색이 상보필터네요. 여기서는 P게인이 낮아서 부드럽지만 다소 지연이 발생하는걸 보실 수 있습니다. 자기가 사용하는 상황에 맞게 튜닝 해야겠죠? ㅠㅠ 이부분이 제일 어려운거 같습니다 ㅜㅜ


팁으로 아두이노에서 dt(한 루프 걸리는 시간)를 구할 때는 millis()나 micros()를 사용하시면 됩니다.

아, delayMicroseconds(int n)함수는 n에 숫자 제한이 있더라구요.. 그것도모르고 사용하다가 고생했네요 ㅠ



------------------------------------------------------------------ 10월 11일 수정 사항 -------------------

코드에서 에러 적분하는 부분에서 +를 하나 빼먹었네요.. 어쩐지 I가 잘 안되더라 ㅠ 수정했슴니당




------------------------------------------------------------------ 14년 2월 2일 오류 정정 -------------------

 "-> (오류 : 하단참고)" 라고 쓴 부분 모두 한가지 오류를 범했습니다.

MPU6050은 내부 레지스터를 이용해서 출력 값의 범위를 조정할 수 있습니다. (데이터시트 참고)

"-90도~90도의 값을 -16383~16383로 주기 때문에" 이 부분이 바뀔수도 있다는 겁니다.

레지스터 조작에 따라 가속도센서같은 경우는 -16383~16393범위에서 -2g~2g의 값을 출력시킬수도 있고  -8g~8g의 값을 출력시킬수도 있습니다.

자이로센서는 -32768~32768로 -250~250[degree/sec]을 출력하던가 -500~500의 값을 출력할수도 있습니다.

물론 범위를 넓히면 정확도는 그만큼 줄겠죠. 

데이터시트부터 차근차근 볼걸 너무 대충봤다는 생각이 듭니다..

논문 쓰면서 다시 돌아보다가 틀린부분이 있어서 바로잡습니다.


------------------------------------------------------------------ 14년 7월 16일 추가사항 -------------------

예전부터 이상하다고 여긴것에 대한 수정사항입니다.

이 글에서 두 센서의 측정치를 각각 각도으로 변환하는데, 오일러각이 아니고 각 축에 대한 각을 따로따로 구한겁니다.

이 부분 혼동하지 마시길 바랍니다. 작년에는 이런거 모르고 그냥 했는데 쿼드가 떴네요... 아마 0도에서 거의 움직이지 않기때문에 두 좌표계 변환을 고려하지 않아도 된 듯 싶습니다.

책에서는 두 센서 모두 오일러각으로 바꿔주던데.. 변환 식을 얼핏 보니 탄젠트가 들어갔던걸로 기억합니다. 0도에서는 탄젠트로 어떻게 계산하는지 이해가 안가서 덮어뒀던 기억이 나네요.


------------------------------------------------------------------ 15년 4월 25일 추가사항 --------------------


글에 잘못된 점이 많아서 새로 포스팅하고 있습니다. 이 글을 지울까 했지만, 이것도 하나의 시행착오고.. 혹시라도 다른 분들이 겪지 않았음 하는 마음에 그대로 두기로 했습니다. 새로운 포스팅은 

가속도, 자이로 센서값을 오일러각으로 변환 - 1

을 참고해주세요~



--------------------------------------------------------------------------------------






'Quadrotor2013' 카테고리의 다른 글

쿼드콥터 중간점검  (2) 2013.10.15
상보필터 게인값 조절하기  (2) 2013.10.11
mpu6050 가속도, 자이로 센서를 융합하기[상보필터] - 1  (9) 2013.09.29
쿼드콥터 PID제어  (1) 2013.08.25
쿼드콥터 시소놀이  (4) 2013.08.25
Posted by 너를위한노래
Quadrotor20132013. 9. 29. 17:41

상보필터 센서 융합에 관한 글을 적다가 센서 설명하는 부분이 길어져서 아예 따로 포스팅하려고 합니다 ㅋ


쿼드콥터의 자세를 측정하기위해 센서가 필요한데, roll, pitch, yaw중 roll, pitch를 측정하기 위한 센서인 가속도, 자이로센서에 대해 포스팅하겠습니다. yaw는 지자기센서가 있어야 정확한 측정이 되므로 제외하구요 ㅋ


roll, pitch, yaw를 모르신다면 이전 포스팅을 참고하시구요. - 쿼드콥터 동역학 모델링_1(기본원리)




가속도 센서는, --------------------------------------------------------------------------------------


말그대로 가속도를 측정하는 센서입니다. 가만히 고정되어 움직이지 않는 상태라면 센서에 중력 가속도만 작용하는 상태겠죠. 그럼 그 중력 가속도를 x, y, z축 벡터 세개로 나누어서 수치로 크기를 표현해줍니다. MPU6050같은 경우는 각 축에대해 -16383~16383까지의 값이 있네요. 딱 부호있는 16비트네요

밑의 그림을 참고하시면 도움이 되실거 같습니다. (회색 상자가 센서입니다)

 



 


하지만 중력가속도 g뿐만이 아니라 다른 외력에도 너무 민감하다는게 단점입니다. 다른 글에는 병진 운동에 취약하다 라고 되어있는데 이해를 돕기위해 좀 극단적인 예를 하나 들어보면 위 그림의 센서가 자유낙하 하고 있는 경우(공기저항무시) g가 0이겠죠? 그럼 센서가 아무리 기울어져 있어도 측정이 안될겁니다. 이처럼 센서의 회전이 아니라 이동에 취약하고 더 나아가 진동에도 약한 단점이 있습니다. 진동을 변위가 작은 이동이라고 보면 되겠네요. 하지만 두번째 그림인 상태에서 아무리 센서를 흔들고 던지고 회전시킨다음에 다시 두번째 상태로 돌아오더라도 흔들기 전과 후의 값이 같다는 특징이 있습니다. 


출력값을 보시면, (가속도센서값을 roll로 변환한 후 출력)


제가 손으로 임의로 실험한거라 손노이즈(?)도 있는거 같은데 여기서 주의깊게 보실 점은 구불구불한 노이즈들(밑의 자이로출력과 비교해보세요)과 멈췄을 때 값이 일정하게 유지된다는 것입니다.


정리하면 가속도 센서는 노이즈가 심하고 움직임의 값이 왜곡될 수 있지만(=부정확하지만) 시간이 지나도 오차가 누적되지 않는다.


자이로센서는, --------------------------------------------------------------------------------------


가속도센서와는 다르게 각속도를 검출하는 센서입니다. 선속도와 각속도의 차이, 속도와 위치의 관계를 안다는 가정 하에 설명할게요~


 


그림그리기가 좀 힘드네요..;; 위 그림에서 빨간선과 파란선의 각도의 변화량을 x, y, z축 각각의 변화량으로 표현해줍니다. 즉, 아무 움직임도 없다면 x, y, z축 값이 모두 0이라는 거죠. 여기서 중요한 점은 각 속도이기 때문에 기울어진 각도(위치)를 구하려면 적분을 해줘야한다는겁니다. 


출력값을 보시면, (자이로센서값을 roll로 변환한 후 출력)


위의 가속도센서 출력값과 같은 구간입니다. 처음보시는 분들은 가속도센서값이 더 정확해 보이시겠지만 자이로센서값이 실제 제 손 움직임과 더 비슷합니다. 다만, 계속 밑으로(마이너스 쪽으로) 발산해 가는데 이것이 자이로센서가 가진 단점입니다. 계속 적분하는 과정에서 센서의 노이즈도 같이 적분되기 때문에 이렇게 드리프트가 생기더라구요. 


정리하면, 자이로 센서는 실제 값과 비슷하지만(=정확하지만) 누적오차가 발생한다.


자 여기서, 가속도 자이로 값으로 같은 현상(roll, pitch같은)을 측정할 수 있지만 서로 장단점이 있다는걸 알 수 있죠, 그리고 서로의 단점이 상대의 장점이 된다는것도요


이 두 센서의 장점을 합치면 아래 그림의 파란색처럼 됩니다.



이걸 합치는 상보 필터에 대해 다음에 포스팅 하겠습니다.





'Quadrotor2013' 카테고리의 다른 글

상보필터 게인값 조절하기  (2) 2013.10.11
mpu6050 가속도, 자이로 센서를 융합하기[상보필터] - 2  (45) 2013.09.29
쿼드콥터 PID제어  (1) 2013.08.25
쿼드콥터 시소놀이  (4) 2013.08.25
현재 작업 환경  (1) 2013.08.08
Posted by 너를위한노래