2021. 4. 2. 19:00ㆍ03. Resources/Matlab & Simulink
Moving Average Filter (이동 평균 필터)
다양한 이산 시간에서의 동적 시스템을 모델링하기 위해서 Simulink를 이용한다.
이번 포스팅에서는 저번에 Matlab에서 구현한 Moving Average Filter를 Simulink에 구현해보고 결과를 확인해볼 것이다.
Moving Average Filter에 대한 설명은 이전 포스팅에 적어놨으니, 이번 포스팅에서는 이산 시간 시스템에 적용하기 위해 어떤 점들을 고려했는지 설명하겠다.
개인적으로, Simulink를 쓰더라도 블록으로 구현하기 복잡한 기능들은 Matlab function 블록으로 처리하는 것을 좋아한다. 블록으로 구현해서 가독성이 떨어져 이해하기 어려울 바에는 그냥 Matlab script로 보는 것이 기능을 이해하는 측면에서는 더 좋다고 생각한다. 그리고 이산 시간 시스템에 적용 가능한 script를 짠다는 말은 블록으로도 언제든 대체할 역량이 있다고 생각하기 때문이다.
이용할 수 있는 전체 코드는 맨 아래에 코드 블록으로 두겠다.
Matlab function 블록으로 처리하기 위해서 script는 함수 형태로 작성해야한다.
실시간으로 들어오는 값을 받을 변수인 In_Value, 필터링된 값을 내보낼 변수인 Out_FilteredValue를 기본으로 둔다.
Window size를 따로 둔 이유는, 동일한 블록을 여러 데이터에 적용해야했기 때문에, 일괄적인 변경을 위해 변수로 처리해서 입력으로 주는 방식을 이용했다.
function Out_FilteredValue = MovingAverageFilter(In_Value, In_WindowSize)
%% 시뮬링크에서 이용할 Moving Average Filter
% 윈도우 사이즈(몇 스텝의 데이터를 볼 것인지) 정의
WindowSize = In_WindowSize;
...
end
실시간 시스템에서 데이터의 이전 값들을 보관하기 위해서 persistent를 이용해서 History 변수를 선언하고, 입력으로 받은 window size에 맞게 0으로 된 배열로 초기화한다.
% 데이터 저장을 위한 History 배열 선언
% - 함수가 실행되더라도 값이 남아있어야하기 때문에 persistent로 선언
persistent History;
if isempty(History)
History = zeros(WindowSize,1);
end
그리고 기존 오프라인 필터링과 다르게, 실시간 시스템에서 고려해야하는 상황은 window size 보다 데이터의 수가 적은 상황이다. 이런 경우에는 들어온 데이터만을 이용해서 필터링을 진행한다. 들어온 데이터의 개수를 측정하기 위해서 Counter 변수를 선언한다.
% 윈도우 사이즈 미만에서의 처리를 위한 Counter 선언
persistent Counter;
if isempty(Counter)
Counter = 1;
end
위에서 선언한 변수들과 입력들로 필터링하는 코드는 아래와 같다.
윈도우 사이즈보다 들어온 데이터 수가 적은 경우, 들어온 값을 다 더하고 Counter로 나눈다.
윈도우 사이즈보다 들어온 데이터 수가 많은 경우, 맨 앞 데이터를 버리고 맨 뒤 값을 추가한 뒤 다 더하고 WindowSize로 나눈다.
그리고 그 값을 내보낸다.
%% 이동 평균 계산
if Counter <= WindowSize
History(Counter) = In_Value;
Out_FilteredValue = sum(History(1:Counter)) / Counter;
Counter = Counter + 1;
else
History(1:end-1) = History(2:end);
History(end) = In_Value;
Out_FilteredValue = sum(History) / WindowSize;
Counter = Counter + 1;
end
위의 코드들의 결과를 첨부하려니까 Matlab이 계속 멈춰서...
결과를 첨부하진 않지만 정상 작동하는 것을 확인했고, 나중에 결과 뽑히면 첨부해야겠다.
이번 포스팅에서는 이산 시간 동적 시스템에서 사용할 수 있는 실시간 Moving Average Filter 에 대해서 작성해봤다.
물론 더 나은 코드들이 있을 수 있지만! 개념적으로는 이정도로만 작성해도 충분할 것 같다.
전체 코드는 아래에 있다. 참고하시길!
전체 코드
function Out_FilteredValue = MovingAverageFilter(In_Value, In_WindowSize)
%% 시뮬링크에서 이용할 Moving Average Filter
% 윈도우 사이즈(몇 스텝의 데이터를 볼 것인지) 정의
WindowSize = In_WindowSize;
% 데이터 저장을 위한 History 배열 선언
% - 함수가 실행되더라도 값이 남아있어야하기 때문에 persistent로 선언
persistent History;
if isempty(History)
History = zeros(WindowSize,1);
end
% 윈도우 사이즈 미만에서의 처리를 위한 Counter 선언
persistent Counter;
if isempty(Counter)
Counter = 1;
end
%% 이동 평균 계산
if Counter <= WindowSize
History(Counter) = In_Value;
Out_FilteredValue = sum(History(1:Counter)) / Counter;
Counter = Counter + 1;
else
History(1:end-1) = History(2:end);
History(end) = In_Value;
Out_FilteredValue = sum(History) / WindowSize;
Counter = Counter + 1;
end
end
'03. Resources > Matlab & Simulink' 카테고리의 다른 글
[Simulink 개발] 시뮬링크 센서 축 회전변환 (0) | 2021.03.30 |
---|---|
[Simulink 개발] C언어로 작성된 코드를 Simulink에서 실행시키는 방법 (2) (0) | 2020.08.19 |
[Simulink 개발] C언어로 작성된 코드를 Simulink에서 실행시키는 방법 (1) (0) | 2020.08.19 |
[Matlab 개발] Moving Average Filter (이동 평균 필터) (0) | 2020.06.25 |