칼만필터를 이용한 네번째 예제는 '가속도계와 자이로를 이용해 헬기의 수평 자세를 알아내기'이다. 헬기의 가속도(m/s2)와 각속도(rad/s)로 부터, 수평면에 대한 헬기의 앞뒤 및 좌우로 기울어진 각도를 알아낸다. 이 예제에서는 헬기의 수평 자세를 위주로 해석해야하기 때문에 세 개의 각도(Euler angle) Roll(ϕ), Pitch(θ), Yaw(ψ) 중 Roll(ϕ)과 Pitch(θ) 정보 만을 이용한다.
센서의 융합을 위해서는 상호 보완을 가장 먼저 고려해야 한다. 즉 각 센서의 단점을 서로 상호보완하는 관계가 되어야 한다는 것이다. 최종적으로 출력값은 각 센서의 장점만을 이용하게 되는 것이다. 이 예제에서는 다음과 같은 방법으로 테스트를 진행한다.
주파수 0.2Hz, 최대 진폭 ± 30°인 정현파로 항법 센서를 진동시킨다. 테스트 절차는 다음과 같다.
1) Roll축 기동(1분)
2) 1분 정지
3) Roll-Pitch축 기동(1분)
4) 1분 정지
5) Pitch축 기동(1분)
자이로 센서를 이용하여 자세 결정하기
자이로센서를 이용해 측정한 각속도는 오일러 각도의 변화율(ϕ˙,θ˙,ψ˙)이 아닌, 헬기의 각속도(p,q,r)를 측정하기 때문에 이를 변환하는 행렬을 적용 후, 적분하여 오일러 각도를 구할 수 있게 된다. 오일러와 각속도의 관계는 1.1과 같다.
코드에 대해 잠깐 설명하자면 이전 각도값을 저장하는 변수인 prevPhi, prevTheta, prevPsi를 선언하였다. 자이로 센서는 이전 값을 기준으로 얼마나 회전했는가를 측정하는 센서이다. 즉, 상대적인 각속도를 측정하기 때문에 (0, 0, 0)라는 상태에서 절대적으로 얼마나 회전했는가를 파악하기 위해선 이전 값을 토대로 누적 합산하여 구할 수 있다. 이를 토대로 구해진 결과는 다음 사진과 같다.
50초에서 250초에는 ±30°의 진폭으로 진동하는 움직임을 잘 나타내고 있다. 하지만 300초 이후부터는 roll축의 기동이 없음에도 불구하고 값이 점점 발산하는 것을 확인할 수 있는데 이는 오차가 누적되고 있다는 것이다. pitch 축의 경우 이상적으로 0°에서 ±30°의 진폭으로 진동하는 움직임을 나타내야 하지만 Roll축 기동의 영향을 받아 오차가 누적되어 값이 발산되는 것을 확인할 수 있다. 자이로 센서의 경우 오차누적으로 인해 값은 편향(biased)되지만, 진동에 대한 변화를 잘 감지하고 있다.
가속도계로 측정한 가속도(fx,fy,fz)에는 중력 가속도와 속도의 크기나 방향이 바뀔 때 생기는 가속도 등 다양한 종류의 가속도가 포함되어 있는 상태이다. 여기서 u,v,w는 이동속도를 의미하고, p,q,r은 회전 각속도, g는 중력 가속도를 나타낸다. 이 가속도 센서를 이용하는 목적은 결국 식 2.1의 가장 우변에 존재하는 roll angle(ϕ)와 pitch angle(θ)를 구하는 것이다. 하지만 이동속도인 (u,v,w)와 (u˙,v˙,w˙)는 알 수 없는 값이므로 roll angle(ϕ)와 pitch angle(θ)을 구할 수 없다. 하지만 다음과 같은 전제조건을 적용하여 가속도 센서를 통해 식 4와 같이 오일러 각도를 구할 수 있다.
<전제조건>
1. 정지 상태일 경우 이동 가속도 (u˙,v˙,w˙)와 이동 속도 (u,v,w)는 모두 0이다.
2. 일정한 속도로 움직이는 경우 이동 가속도가 0이고, 자세의 변화가 거의 없으므로 각속도 (p,q,r)도 0이다.
3. 따라서 3.1과 같이 표현된다.
function [phi, theta, psi] = EulerKalman(A, z)
persistent H Q R
persistent x_hat P
persistent firstRun
if isempty(firstRun)
H = eye(4);
% Initial Noise
Q = 0.0001 * eye(4);
R = 10 * eye(4);
% Initial Value
x_hat = [1, 0, 0, 0]';
P = 1.0 * eye(4);
firstRun = 1;
end
xp = A * x_hat;
Pp = A*P*A' + Q;
K = Pp*H'*inv(H*Pp*H' + R);
x_hat = xp + K*(z - H*xp);
P = Pp - K*H*Pp;
% Quaternion to Euler
phi = atan2(2*(x_hat(3)*x_hat(4) + x_hat(1)*x_hat(2)), 1 - 2*(x_hat(2)^2 + x_hat(3)^2));
theta = -asin(2*(x_hat(2)*x_hat(4) - x_hat(1)*x_hat(3)));
psi = atan2(2*(x_hat(2)*x_hat(3) + x_hat(1)*x_hat(4)), 1 - 2*(x_hat(3)^2+x_hat(4)^2));
결과
자이로 센서와 가속도 센서의 융합을 통해 자이로의 누적 오차가 제거 된것을 확인할 수 있다. 결론적으로 글의 서두에서 말했듯이 센서의 융합을 위해서는 상호 보완을 가장 먼저 고려해야 한다. 즉 각 센서의 단점을 서로 상호보완하는 관계가 되어야 한다는 것이다. 최종적으로 출력값은 각 센서의 장점만을 이용하게 되는 것이다.