% TOGAC46_RGC_RealIdentification.m % This file will analyze the input and output velocity data for the X Y and % Z axis of the real galen robot for tests that are 10 seconds long on a % chip input from 0.01 to 2 Hz % Modified 05-4-2023 % Created by Brevin Banks clc close all % True X data % load the data Outdata = load('RealSystemCartesianData/IdentificationOut_Xrun1_2023_05_05.txt'); Indata = load('RealSystemCartesianData/IdentificationIn_Xrun1_2023_05_05.txt'); % X data in position 2, more accurate time data in position 8 % Take the derivative of the output position data Time_data = Outdata(:,8); data = Outdata(:,2); Vout = []; for k=2:length(data(:)) Vout(k-1) = (data(k)-data(k-1))/(Time_data(k)-Time_data(k-1)); end Vout =[Vout Vout(end)]; % Add lagging points lost due to finite difference method % get the FFT of the data to determine the necessary cuttoff frequency wc Ls = length(Vout);% Signal length Fs = 200;% Sampling frequency Ts = 1/Fs;% Sampling period tv = (0:Ls-1)*Ts; % Time vector F = fft(Vout);% Calling fft() function for signal Xfv PS2 = abs(F/Ls);% Double sampling plot PS1 = PS2(1:Ls/2+1);% Single sampling plot PS1(2:end-1) = 2*PS1(2:end-1); f = Fs*(0:(Ls/2))/Ls; % Appropriate cuttoff frequency for X wc = 75; Voutfilter = [0]; Ts = []; % Apply a first order filter to the Vout data for k = 2:length(Vout)-2 Ts(k) = (Outdata(k,1)-Outdata(k-1,1)); % Calculate the timestep Voutfilter(k) = (Ts(k)*wc*(Vout(k)+Vout(k-1))-Voutfilter(k-1)*(Ts(k)*wc-2))/(2+Ts(k)*wc);% first order low pass filter from p/(s+p) end Voutfilter = [Voutfilter Voutfilter(end-1:end)]; % Add lagging points lost due to finite difference method % Integrate the input velocity to get the position reference In = cumtrapz(Indata(:,1),Indata(:,2)); figure(1) subplot(3,1,1) hold on plot(Indata(:,1),In) plot(Time_data,data-data(1)) ylabel('Position (mm)') legend('Pref','Pout') subplot(3,1,2) hold on plot(Indata(:,1),Indata(:,2)) plot(Time_data,Vout) plot(Time_data,Voutfilter,'k') xlabel('Time (s)') ylabel('Velocity (mm/s)') legend('Vref','Vout','VoutFilt75HzWc') subplot(3,1,3) hold on plot(f,PS1) xlabel('Hz') ylabel('|Amplitude X fft|') dt = mean(Ts); Vin = Indata(:,2)'; [tf1,ss2] = IdentifySystem(Voutfilter,Vin,dt) % TFX = exp(-0.115*s) * 9.883e04/(s^2 + 12.47*s + 1.034e05) %% clc close all % True Y data % load the data Outdata = load('RealSystemCartesianData/IdentificationOut_Yrun1_2023_05_05.txt'); Indata = load('RealSystemCartesianData/IdentificationIn_Yrun1_2023_05_05.txt'); % Y data in position 3, more accurate time data in position 8 % Take the derivative of the output position data Time_data = Outdata(:,8); data = Outdata(:,3); Vout = []; for k=2:length(data(:)) Vout(k-1) = (data(k)-data(k-1))/(Time_data(k)-Time_data(k-1)); end Vout =[Vout Vout(end)]; % Add lagging points lost due to finite difference method % get the FFT of the data to determine the necessary cuttoff frequency wc Ls = length(Vout);% Signal length Fs = 200;% Sampling frequency Ts = 1/Fs;% Sampling period tv = (0:Ls-1)*Ts; % Time vector F = fft(Vout);% Calling fft() function for signal Xfv PS2 = abs(F/Ls);% Double sampling plot PS1 = PS2(1:Ls/2+1);% Single sampling plot PS1(2:end-1) = 2*PS1(2:end-1); f = Fs*(0:(Ls/2))/Ls; % Appropriate cuttoff frequency for X wc = 75; Voutfilter = [0]; Ts = []; % Apply a first order filter to the Vout data for k = 2:length(Vout)-2 Ts(k) = (Outdata(k,1)-Outdata(k-1,1)); % Calculate the timestep Voutfilter(k) = (Ts(k)*wc*(Vout(k)+Vout(k-1))-Voutfilter(k-1)*(Ts(k)*wc-2))/(2+Ts(k)*wc);% first order low pass filter from p/(s+p) end Voutfilter = [Voutfilter Voutfilter(end-1:end)]; % Add lagging points lost due to finite difference method % Integrate the input velocity to get the position reference In = cumtrapz(Indata(:,1),Indata(:,3)); figure(1) subplot(3,1,1) hold on plot(Indata(:,1),In) plot(Time_data,data-data(1)) ylabel('Position (mm)') legend('Pref','Pout') title('Y response from Chirp 0.01 to 0.5') subplot(3,1,2) hold on plot(Indata(:,1),Indata(:,3)) plot(Time_data,Vout) plot(Time_data,Voutfilter,'k') xlabel('Time (s)') ylabel('Velocity (mm/s)') legend('Vref','Vout','VoutFilt75HzWc') subplot(3,1,3) hold on plot(f,PS1) xlabel('Hz') ylabel('|Amplitude Y fft|') dt = mean(Ts); Vin = Indata(:,3)'; [tf1,ss2] = IdentifySystem(Voutfilter,Vin,dt) % TFY = exp(-0.0599*s) * 1.607e07/(s^2 + 1.971e05*s + 1.655e07) %% clc close all % True Z data % load the data Outdata = load('RealSystemCartesianData/IdentificationOut_Zrun1_2023_05_05.txt'); Indata = load('RealSystemCartesianData/IdentificationIn_Zrun1_2023_05_05.txt'); % Z data in position 4, more accurate time data in position 8 % Take the derivative of the output position data Time_data = Outdata(:,8); data = Outdata(:,4); Vout = []; for k=2:length(data(:)) Vout(k-1) = (data(k)-data(k-1))/(Time_data(k)-Time_data(k-1)); end Vout =[Vout Vout(end)]; % Add lagging points lost due to finite difference method % get the FFT of the data to determine the necessary cuttoff frequency wc Ls = length(Vout);% Signal length Fs = 200;% Sampling frequency Ts = 1/Fs;% Sampling period tv = (0:Ls-1)*Ts; % Time vector F = fft(Vout);% Calling fft() function for signal Xfv PS2 = abs(F/Ls);% Double sampling plot PS1 = PS2(1:Ls/2+1);% Single sampling plot PS1(2:end-1) = 2*PS1(2:end-1); f = Fs*(0:(Ls/2))/Ls; % Appropriate cuttoff frequency for X wc = 75; Voutfilter = [0]; Ts = []; % Apply a first order filter to the Vout data for k = 2:length(Vout)-2 Ts(k) = (Outdata(k,1)-Outdata(k-1,1)); % Calculate the timestep Voutfilter(k) = (Ts(k)*wc*(Vout(k)+Vout(k-1))-Voutfilter(k-1)*(Ts(k)*wc-2))/(2+Ts(k)*wc);% first order low pass filter from p/(s+p) end Voutfilter = [Voutfilter Voutfilter(end-1:end)]; % Add lagging points lost due to finite difference method % Integrate the input velocity to get the position reference In = cumtrapz(Indata(:,1),Indata(:,4)); figure(1) subplot(3,1,1) hold on plot(Indata(:,1),In) plot(Time_data,data-data(1)) ylabel('Position (mm)') legend('Pref','Pout') title('Z response from Chirp 0.01 to 0.5') subplot(3,1,2) hold on plot(Indata(:,1),Indata(:,4)) plot(Time_data,Vout) plot(Time_data,Voutfilter,'k') xlabel('Time (s)') ylabel('Velocity (mm/s)') legend('Vref','Vout','VoutFilt75HzWc') subplot(3,1,3) hold on plot(f,PS1) xlabel('Hz') ylabel('|Amplitude Z fft|') dt = mean(Ts); Vin = Indata(:,4)'; [tf1,ss2] = IdentifySystem(Voutfilter,Vin,dt) % TFZ = exp(-0.015*s)*2.075e04/(s^2 + 749.4*s + 2.098e04) %% % This function will take input and output data from a control response % % Inputs: % Vout - output data from control response % Vin - input data from control % dt - the estimated sampling time used for control % Outputs: % Gest - the estimated transfer function using the tfest method with 2nd % order guess % Gest2 - the estimated transfer functino using the ssest method function [Gest, Gest2] = IdentifySystem(Vout,Vin,dt) s = tf('s'); u = Vin(1,:)'; yreal = Vout'; data = iddata(yreal,u,dt); Gest = tfest(data,2,0,NaN) figure(2) opt = compareOptions; opt.InitialCondition = 'z'; compare(data,Gest,opt) set(findall(gca, 'Type', 'Line'), 'LineWidth', 4) xlabel("Time (s)") subtitle("2nd Order Est with no Zeros") ylabel('Velocity (m/s)') grid on % estimate the delay term delay_samples = delayest(data); % Remove delay from output yreal_no_delay = yreal(delay_samples+1:end); % Repackage offset data data_offset = iddata(yreal_no_delay, u(1:end-delay_samples), dt); % Fit data to a state space model of unknown oder Gss = ssest(data_offset, 1:10); % Convert to tf and add in the delay term Gest2 = tf(Gss)*exp(-delay_samples * dt * s) figure(3) opt = compareOptions; opt.InitialCondition = 'z'; compare(data,Gest2,opt) set(findall(gca, 'Type', 'Line'), 'LineWidth', 4) xlabel(["Time (s)"]) subtitle("SS Estimate") ylabel('Velocity (m/s)') grid on end