HCI/이론

[Haptics - Dynamic compensation] Calibration Using NI DAQ, Python and Matlab

sillon 2025. 2. 25. 19:21
728x90
반응형

이번 게시글에서는 앞서 포스팅한 게시글

https://sillon-coding.tistory.com/631

 

[Haptics - Dynamic compensation] Matlab에서 Chirp Signal 출력하기

Chirp SignalChirp Signal은 주파수가 점진적으로 증가하거나 감소하는 특성을 가진 신호로, 다음과 같은 특징이 있다.Chirp-Up: 주파수가 점차 증가하는 신호Chirp-Down: 주파수가 점차 감소하는 신호넓은

sillon-coding.tistory.com

 

에서 추출한 Chirp Signal을 바탕으로 30~ 300 Hz 주파수 대역에서 진동을 사용하도록 Calibaration 을 진행할것입니다.

 

간단히 코드만 짚고 넘어가겠습니다.

chirp_test.m (matlab 코드입니다.) 

% 샘플링 레이트 및 시간 벡터 설정
Fs = 10000;  % 샘플링 주파수 (Hz)
T = 10;       % 총 지속 시간 (초)
t = linspace(0, T, Fs * T); % 시간 벡터

% Chirp Signal 생성 (30Hz -> 300Hz)
f0 = 30;  % 시작 주파수 (Hz)
f1 = 300; % 종료 주파수 (Hz)
y = chirp(t, f0, T, f1);

% 생성된 신호 플로팅
figure;
plot(t, y);
xlabel('Time (s)');
ylabel('Amplitude');
title('Chirp Signal (30Hz to 300Hz)');
grid on;

% 텍스트 파일로 저장
fileID = fopen('chirp_signal.txt', 'w');
fprintf(fileID, '%f\n', y);
fclose(fileID);

 

이제 여기서 Chirp Signal의 평균을 보정해주는 식을 찾겠습니다.

dynamic_compensation.m

 

%% 전역변수
samplingRate = 10000;
time = 10;
samps = samplingRate * time;
fmin = 30;
fmax = 300;
voltage = 1;
t = linspace(0, time, samps);
f = linspace(0, samplingRate, samps);
iodelay = 0;
Ts = 1/samplingRate;
PI = 3.1415926536;



%% 입력
chrpName=sprintf('chirp_signal.txt');
fileName=sprintf('Chirp\\Chirp_Accels_Mean.txt');
chrp = textread(chrpName, '%f');
mtr = textread(fileName, '%f');
tr = mtr - mean(mtr);
HighpassedMotor = highpass(tr, fmin, samplingRate, 'Steepness', 0.9);

chrp = chirp(t, fmin, 1, fmax);
%%
fftChirp = fft(chrp);
fftOutput = fft(HighpassedMotor);
%InversetransferFunction = fftChirp ./ fftOutput;

%input output data encapsulation
%iddataTF = iddata(HighpassedMotor, chrp, 1/samplingRate);
iddataITF = iddata(chrp', HighpassedMotor, 1/samplingRate);

EstimatedITF = etfe(iddataITF, [], samplingRate*time);
%etfe Smoothing

[TFmag, TFphase, TFwout] = bode(EstimatedITF);
TFestsys = tfest(EstimatedITF, 14,12 , iodelay, 'Ts', Ts, 'Feedthrough', true, tfestOptions('WeightingFilter', [30*(2*PI), 300*(2*PI)]));

compare(ITFestsys, EstimatedITF);

현재 그래프(이미지)와 조정해야 할 부분 연결하기

현재 MATLAB의 compare(ITFestsys, EstimatedITF);에서 나타난 파란색(측정된 ITF)과 회색(추정된 ITF) 그래프가 겹쳐져야 한다.
즉, 추정된 전달 함수(Identified Transfer Function, ITF)가 실제 측정된 데이터와 일치하도록 조정해야 한다.


1️⃣ 그래프 분석 (회색 vs. 파란색)

  • 회색 그래프: 현재 모델이 추정한 주파수 응답(Estimated ITF)
  • 파란색 그래프: 실제 측정된 가속도 응답(실제 ITF 데이터)
  • 차이점: 일부 주파수 구간에서 두 그래프가 일치하지 않고 차이가 발생함

📌 이 차이를 줄이려면, 전달 함수의 차수(14,12)를 조정해야 한다.
차수가 너무 낮으면 전체적인 경향을 따라가지 못하고, 너무 높으면 특정 구간에서만 잘 맞을 수 있으므로,
최적의 차수를 찾아야 한다.


2️⃣ 해결 방법: tfest() 함수의 전달 함수 차수 조정

MATLAB의 tfest()를 사용하여 전달 함수(Transfer Function)의 차수를 조정할 수 있다.

ITFestsys = tfest(EstimatedITF, 14, 12, iodelay, 'Ts', Ts, ... 'Feedthrough', true, tfestOptions('WeightingFilter', [30*(2*PI), 300*(2*PI)]));
  • 14,12: 현재 사용된 전달 함수의 차수 (분자 14차, 분모 12차).
  • iodelay: 입출력 지연값.
  • 'WeightingFilter': 특정 주파수 대역(30Hz~300Hz)에서 성능을 최적화하도록 설정.

차수를 조정하는 이유

  • 전달 함수의 차수가 너무 낮으면, 모델이 단순해져서 전체적인 주파수 응답을 충분히 따라가지 못한다.
  • 전달 함수의 차수를 조정하면, 모델이 실제 측정값(파란색)과 더 유사한 주파수 응답을 보이도록 개선할 수 있다.
  • 적절한 차수를 찾으면 전 주파수 대역에서 파란색과 회색이 최대한 일치하도록 조정할 수 있다.

3️⃣ 차수 변경에 따른 조정

차수를 조정하면서 파란색과 회색이 더 잘 겹치는 값을 찾을 수 있다.
예를 들어:

ITFestsys = tfest(EstimatedITF, 18, 16, iodelay, 'Ts', Ts, ... 'Feedthrough', true, tfestOptions('WeightingFilter', [30*(2*PI), 300*(2*PI)]));

또는

ITFestsys = tfest(EstimatedITF, 20, 18, iodelay, 'Ts', Ts, ... 'Feedthrough', true, tfestOptions('WeightingFilter', [30*(2*PI), 300*(2*PI)]));

이렇게 차수를 높이거나 낮추면서 파란색과 회색이 최대한 겹치는 값을 찾으면 된다. 


4️⃣ 결론

  • 현재 compare(ITFestsys, EstimatedITF);의 결과에서 회색(추정값)과 파란색(실제 측정값)이 일치하도록 조정해야 한다.
  • 이를 위해 tfest()의 전달 함수 차수(14,12)를 바꿔가면서 실험해야 한다.
  • 차수가 너무 낮으면 전체적인 경향을 따라가지 못하고, 너무 높으면 특정 구간에서만 잘 맞을 수 있으므로 최적의 차수를 찾는 것이 중요하다.
  • 차수를 높이면 세밀한 주파수 응답을 추정할 수 있으며, 이를 통해 모델이 실제 데이터를 최대한 반영하도록 조정할 수 있다.

📌 최종 목표: 파란색과 회색이 최대한 겹치는지 확인하면서 전달 함수 차수를 조정하여, 측정된 데이터를 최대한 반영한 모델을 만드는 것이다.

 

ITFestsys = tfest(EstimatedITF, 15,11 , iodelay, 'Ts', Ts, 'Feedthrough', true, tfestOptions('WeightingFilter', [30*(2*PI), 300*(2*PI)]));

 

차수를 높게 한다고 잘되는건 아니다. (되도록 9 안의 값을 찾으면서 찾자)

 

차수 예시는 아래와 같음

 

728x90
반응형