% TOGAC31_AMBF_GalenSystemIdent.m % This file was used to analyze the input and and output data for the galen % surgical robot in AMBF. This was used for the assumption the the robot % could be evaluated as a mass spring damper where the joints are all held % at their 0 positions, and the 3 carriage joints are controlled with % velocity control simulatneously. The input for the 3 carriage joints was % identical, lumping their response together. They should opperate in % parallel and move the robot like a mass linearly along the z axis. % The response of a step input of magnitud 0.5 was applied for the step % respone, with the intial pose of the carriage joints at the bottom of the base. % The response for a chirp input from 100Hz to 1hz was applied for 50 % seconds with the carriage joints in the middle of the joint limits % (0.21m) % The systems were identified using the tfest method and ssest methods from % matlab's system identification toolbox % Created by Brevin Banks % Modified April 1 2023 %% Chirp input % load the data dt = 0.1087; % measured time step per sampling loop Vout100hzto1hzChirp = load('Vout100hzto1hzChirp.mat'); Vin100hzto1hzChirp = load('Vin100hzto1hzChirp.mat'); Vout = (Vout100hzto1hzChirp.Vout100hzto1hz(1,:) + Vout100hzto1hzChirp.Vout100hzto1hz(2,:) + Vout100hzto1hzChirp.Vout100hzto1hz(3,:))/3; Vin = Vin100hzto1hzChirp.Vin100hzto1hz(1,:); IdentifySystem(Vout,Vin,dt) % tfest Transfer result % tf_chirp_no_grav = % 1.413e05 % ----------------------- % s^2 + 1465 s + 1.417e05 % 83.45% match % ssest Transfer result % tf_chirp_no_grav = % 4.894 s + 630.6 % --------------------- % s^2 + 26.33 s + 641.6 % 84.14% match %% Step Input No Gravity % load the data dt = 0.0746;% measured time step per sampling loop VoutStep0_05Nograv = load('VoutStep0_05Nograv.mat'); VinStep0_05 = load('VinStep0_05.mat'); Vout = (VoutStep0_05Nograv.cv(1,:) + VoutStep0_05Nograv.cv(2,:) + VoutStep0_05Nograv.cv(3,:))/3; Vin = VinStep0_05.rv(1,:); IdentifySystem(Vout,Vin,dt) % Step input only has tfest result as ssest was a very poor match % tf_step_no_grav = % 5262 % -------------------- % s^2 + 138.6 s + 5265 % 84.15% match %% Step Input Gravity % load the data dt = 0.0971;% measured time step per sampling loop VoutStep0_05Grav = load('VoutStep0_05Grav.mat'); VinStep0_05 = load('VinStep0_05Grav.mat'); Vout = (VoutStep0_05Grav.cv(1,:) + VoutStep0_05Grav.cv(2,:) + VoutStep0_05Grav.cv(3,:))/3; Vin = VinStep0_05.rv(1,:); IdentifySystem(Vout,Vin,dt) % tfest result % tf_step_grav = % 1124 % exp(-0.0971*s) * ------------------- % s^2 + 50.9 s + 1274 % 98.5% match %% % This function will take input and output joint command data for the galen % carriage joints. It only needs the data for one joint as the % identification was made with the assumption that the galen was a lumped % mass. It uses the tfest and ssest methods from the system identification % toolbox. % % 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) close all figure(1) 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 ylim([-0.06 0.06]) % 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(2) 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 ylim([-0.06 0.06]) end