310 lines
10 KiB
Matlab
310 lines
10 KiB
Matlab
%% Clear Workspace and Close figures
|
|
clear; close all; clc;
|
|
|
|
%% Intialize Laplace variable
|
|
s = zpk('s');
|
|
|
|
%% Path for functions, data and scripts
|
|
addpath('./mat/'); % Path for data
|
|
|
|
%% Colors for the figures
|
|
colors = colororder;
|
|
|
|
%% Force Sensor Calibration
|
|
% Load measurement data
|
|
load('calibration_force_sensor.mat', 't', 'F', 'Fc')
|
|
|
|
% Remove any offset such that they are both measuring no force when not in contact.
|
|
F = F - mean(F( t > 0.5 & t < 1.0)); % FC2231 [N]
|
|
Fc = Fc - mean(Fc(t > 0.5 & t < 1.0)); % XFL212R [N]
|
|
|
|
% Only get useful stroke
|
|
F = F( t > 2 & t < 2.2);
|
|
Fc = Fc(t > 2 & t < 2.2);
|
|
t = t( t > 2 & t < 2.2);
|
|
|
|
% Make a line fit
|
|
fit_F = polyfit(Fc, F, 1);
|
|
|
|
% Estimate the gain mismatch
|
|
F_gain_mismatch = 100*(1 - fit_F(1)); % in %
|
|
|
|
% Estimate non-linearity of the sensors
|
|
F_non_linearity = 100*(F - (Fc*fit_F(1) + fit_F(2)))./Fc; % in %
|
|
|
|
%% Measured two forces and linear fit
|
|
figure;
|
|
yyaxis left
|
|
hold on;
|
|
plot(Fc, F, '.', 'DisplayName', 'Raw Data');
|
|
plot([0, 6], [0,6]*fit_F(1) + fit_F(2), '-', 'color', [colors(3,:), 0.5], 'DisplayName', 'Line Fit');
|
|
hold off;
|
|
xlabel('XFL212R [N]'); ylabel('FC2231 [N]');
|
|
xlim([0,6]); ylim([0,6]);
|
|
xticks([0:6])
|
|
yticks([0:6])
|
|
|
|
yyaxis right
|
|
plot(Fc, movmean(F_non_linearity, 200), '-', 'DisplayName', 'Non linearity');
|
|
ylim([-0.15, 0.15]);
|
|
ylabel('Non Linearity [$\%$]')
|
|
|
|
leg = legend('location', 'southeast', 'FontSize', 8, 'NumColumns', 1);
|
|
leg.ItemTokenSize(1) = 15;
|
|
|
|
%% Estimaetd load cell stiffness
|
|
% Load measurement data
|
|
load('force_sensor_stiffness_meas.mat', 't', 'F', 'd')
|
|
|
|
% Remove offset
|
|
F = F - mean(F(t > 0.5 & t < 1.0));
|
|
|
|
% Select important part of data
|
|
F = F( t > 4.55 & t < 7.24);
|
|
d = d( t > 4.55 & t < 7.24); d = d - d(1);
|
|
t = t( t > 4.55 & t < 7.24);
|
|
|
|
% Linear fit
|
|
fit_k = polyfit(F(F<10), d(F<10), 1);
|
|
|
|
%% Displacement as a function of the measured force
|
|
figure;
|
|
hold on;
|
|
plot(F, 1e6*d, 'k-', 'DisplayName', 'Raw Data');
|
|
plot(F([1,end]), 1e6*(F([1,end])*fit_k(1) + fit_k(2)), '--', 'DisplayName', sprintf('Fit, $k_F \\approx %.2f N/\\mu m$', 1e-6/fit_k(1)));
|
|
hold off;
|
|
xlabel('Force [$N$]'); ylabel('Displacement [$\mu m$]');
|
|
xlim([0,45]); ylim([0,60]);
|
|
legend('location', 'southeast', 'FontSize', 8);
|
|
|
|
%% Estimate the bending stiffness and stroke from the measurement - First Flexible joint
|
|
% Load Measured Data for first flexible joint
|
|
load('meas_stiff_flex_1_x.mat', 't', 'F', 'd');
|
|
|
|
% Start measurement at t = 0.2 s
|
|
d = d(t > 0.2);
|
|
F = F(t > 0.2);
|
|
t = t(t > 0.2); t = t - t(1);
|
|
|
|
% Zero the force
|
|
F = F - mean(F(t < 0.2));
|
|
|
|
% Find when the force sensor touches the flexible joint
|
|
i_l_start = find(F > 0.3, 1, 'first');
|
|
|
|
% Compute torque and angular displacement
|
|
h = 22.5e-3; % Height [m]
|
|
Tx = h * F; % Applied torque in [Nm]
|
|
thetax = atan2(d - d(i_l_start), h); % Measured angle in [rad]
|
|
|
|
% Find then the maximum torque is applied
|
|
[~, i_s_stop] = max(Tx);
|
|
% Linear region stops ~ when 90% of the stroke is reached
|
|
i_l_stop = find(thetax > 0.9*thetax(i_s_stop), 1, 'first');
|
|
% Mechanical "Stop" region start ~20Nmm before maximum torque is applied
|
|
i_s_start = find(Tx > max(Tx)-20e-3, 1, 'first');
|
|
|
|
% Linear fit in the "linear" region
|
|
fit_l = polyfit(Tx(i_l_start:i_l_stop), thetax(i_l_start:i_l_stop), 1);
|
|
|
|
% Linear fit in the "mechanical stop" region
|
|
fit_s = polyfit(Tx(i_s_start:i_s_stop), thetax(i_s_start:i_s_stop), 1);
|
|
|
|
% Reset displacement more precisely based on fit
|
|
thetax = thetax - fit_l(2);
|
|
fit_s(2) = fit_s(2) - fit_l(2);
|
|
fit_l(2) = 0;
|
|
|
|
%% Estimation of the bending stiffness
|
|
kRx_l = 1/fit_l(1); % Bending Stiffness [Nm/rad]
|
|
kRx_s = 1/fit_s(1); % Mechanical "Stop" Stiffness [Nm/rad]
|
|
|
|
%% Estimation of the bending stroke
|
|
% This is done by finding the intersection of the two linear fits
|
|
theta_max = fit_l(1)*fit_s(2)/(fit_l(1) - fit_s(1)); % Maximum angular stroke [rad]
|
|
Tx_at_theta_max = (fit_s(2) - fit_l(2))/(fit_l(1) - fit_s(1));
|
|
|
|
%% Measured force and displacement as a function of time
|
|
figure;
|
|
yyaxis left
|
|
hold on;
|
|
plot(t, F);
|
|
plot(0.8*cos(0:0.01:2*pi)+0.8, ...
|
|
2.8*sin(0:0.01:2*pi)-1, 'k--', 'HandleVisibility', 'off');
|
|
text(1.8, -1.2, sprintf('Not in\ncontact'), 'horizontalalignment', 'left');
|
|
plot(0.4*cos(0:0.01:2*pi)+3, ...
|
|
1.1*sin(0:0.01:2*pi)+4.8, 'k--');
|
|
text(3.5, 4.8, sprintf('Mechanical\nStop'), 'horizontalalignment', 'left');
|
|
hold off;
|
|
ylabel('Force $F_y$ [N]');
|
|
ylim([-4, 6])
|
|
ylimr = get(gca,'Ylim');
|
|
|
|
yyaxis right
|
|
plot(t, 1e3*d);
|
|
xlabel('Time [s]');
|
|
ylabel('Displacement $d_y$ [mm]');
|
|
xlim([0,5]);
|
|
% Make the force and displacement superimpose
|
|
ylim([0.364 - 4*(0.8315-0.364)/4.095, 0.364 + 6*(0.8315-0.364)/4.095])
|
|
|
|
% Regions where to plot the fitted data
|
|
Tx_l_fit = [0, Tx_at_theta_max];
|
|
Tx_s_fit = [Tx_at_theta_max, Tx(i_s_stop)];
|
|
|
|
figure;
|
|
hold on;
|
|
plot(Tx(1:i_s_stop), 1e3*thetax(1:i_s_stop), '-k', 'DisplayName', 'Raw data')
|
|
plot(Tx_l_fit, 1e3*(Tx_l_fit*fit_l(1) + fit_l(2)), '--', 'DisplayName', sprintf('$k_{R_x} = %.1f$ Nm/rad', kRx_l))
|
|
plot(Tx_s_fit, 1e3*(Tx_s_fit*fit_s(1) + fit_s(2)), '--', 'DisplayName', sprintf('$k_{R_x,stop} = %.0f$ Nm/rad', kRx_s))
|
|
plot([0, Tx_at_theta_max], [1e3*theta_max, 1e3*theta_max], 'k--', 'HandleVisibility', 'off')
|
|
plot([0, Tx_at_theta_max], [0, 0], 'k--', 'HandleVisibility', 'off')
|
|
anArrow = annotation('doublearrow', 'LineWidth', 0.5);
|
|
anArrow.Parent = gca;
|
|
anArrow.Position = [0.05, 0, 0, 1e3*fit_l(1)*fit_s(2)/(fit_l(1) - fit_s(1))];
|
|
text(0.052, 0.4*1e3*fit_l(1)*fit_s(2)/(fit_l(1) - fit_s(1)), sprintf('$\\theta_{x,\\max} = %.1f$ mrad', 1e3*theta_max), 'horizontalalignment', 'left');
|
|
hold off;
|
|
xlabel('Torque $T_x$ [Nm]');
|
|
ylabel('Angle $\theta_x$ [mrad]');
|
|
xlim([0, 0.15]);
|
|
ylim([-5,25]);
|
|
leg = legend('location', 'southeast', 'FontSize', 8);
|
|
leg.ItemTokenSize(1) = 15;
|
|
|
|
%% Measure the bending stiffness and Stroke for all the flexible joints
|
|
figure;
|
|
hold on;
|
|
|
|
%% Start with the X-bending
|
|
% Initialize variables
|
|
Rx = zeros(1,16); % Bending stiffnesses [Nm/rad]
|
|
kSx = zeros(1,16); % Bending stiffnesses at "stop" [Nm/rad]
|
|
Rmx = zeros(1,16); % Bending stroke [rad]
|
|
|
|
for i = 1:16
|
|
% Load the data
|
|
load(sprintf('meas_stiff_flex_%i_x.mat', i), 't', 'F', 'd');
|
|
|
|
% Start measurement at t = 0.2 s
|
|
d = d(t > 0.2);
|
|
F = F(t > 0.2);
|
|
t = t(t > 0.2); t = t - t(1);
|
|
|
|
% Zero the force
|
|
F = F - mean(F(t < 0.2));
|
|
|
|
% Find when the force sensor touches the flexible joint
|
|
i_l_start = find(F > 0.3, 1, 'first');
|
|
|
|
% Zero the displacement when it comes in contact
|
|
d = d - d(i_l_start);
|
|
|
|
% Compute torque and angular displacement
|
|
h = 22.5e-3; % Height [m]
|
|
Tx = h * F; % Applied torque in [Nm]
|
|
thetax = atan2(d, h); % Measured angle in [rad]
|
|
|
|
% Find then the maximum torque is applied
|
|
[~, i_s_stop] = max(Tx);
|
|
% Linear region stops ~ when 90% of the stroke is reached
|
|
i_l_stop = find(thetax > 0.9*thetax(i_s_stop), 1, 'first');
|
|
% Mechanical "Stop" region start ~20Nmm before maximum torque is applied
|
|
i_s_start = find(Tx > max(Tx)-20e-3, 1, 'first');
|
|
|
|
% Linear fit in the "linear" region
|
|
fit_l = polyfit(Tx(i_l_start:i_l_stop), thetax(i_l_start:i_l_stop), 1);
|
|
|
|
% Linear fit in the "mechanical stop" region
|
|
fit_s = polyfit(Tx(i_s_start:i_s_stop), thetax(i_s_start:i_s_stop), 1);
|
|
|
|
% Reset displacement more precisely based on fit
|
|
thetax = thetax - fit_l(2);
|
|
fit_s(2) = fit_s(2) - fit_l(2);
|
|
fit_l(2) = 0;
|
|
|
|
% Estimation of the bending stiffness and bending stroke
|
|
kRx(i) = 1/fit_l(1); % Bending Stiffness [Nm/rad]
|
|
kSx(i) = 1/fit_s(1); % Mechanical "Stop" Stiffness [Nm/rad]
|
|
Rmx(i) = fit_l(1)*fit_s(2)/(fit_l(1) - fit_s(1)); % Maximum angular stroke [rad]
|
|
|
|
if i == 1
|
|
plot(Tx(1:10:i_s_stop), 1e3*thetax(1:10:i_s_stop), '-', 'color', [colors(1,:), 0.4], ...
|
|
'DisplayName', '$k_{R_x}$')
|
|
else
|
|
plot(Tx(1:10:i_s_stop), 1e3*thetax(1:10:i_s_stop), '-', 'color', [colors(1,:), 0.4], ...
|
|
'HandleVisibility', 'off')
|
|
end
|
|
end
|
|
|
|
%% Continue with the Y-bending
|
|
% Initialize variables
|
|
kRy = zeros(1,16); % Bending stiffnesses [Nm/rad]
|
|
kSy = zeros(1,16); % Bending stiffnesses at "stop" [Nm/rad]
|
|
Rmy = zeros(1,16); % Bending stroke [rad]
|
|
|
|
for i = 1:16
|
|
% Load the data
|
|
load(sprintf('meas_stiff_flex_%i_y.mat', i), 't', 'F', 'd');
|
|
|
|
% Start measurement at t = 0.2 s
|
|
d = d(t > 0.2);
|
|
F = F(t > 0.2);
|
|
t = t(t > 0.2); t = t - t(1);
|
|
|
|
% Zero the force
|
|
F = F - mean(F(t < 0.2));
|
|
|
|
% Find when the force sensor touches the flexible joint
|
|
i_l_start = find(F > 0.3, 1, 'first');
|
|
|
|
% Zero the displacement when it comes in contact
|
|
d = d - d(i_l_start);
|
|
|
|
% Compute torque and angular displacement
|
|
h = 22.5e-3; % Height [m]
|
|
Ty = h * F; % Applied torque in [Nm]
|
|
thetay = atan2(d, h); % Measured angle in [rad]
|
|
|
|
% Find then the maximum torque is applied
|
|
[~, i_s_stop] = max(Ty);
|
|
% Linear region stops ~ when 90% of the stroke is reached
|
|
i_l_stop = find(thetay > 0.9*thetay(i_s_stop), 1, 'first');
|
|
% Mechanical "Stop" region start ~20Nmm before maximum torque is applied
|
|
i_s_start = find(Ty > max(Ty)-20e-3, 1, 'first');
|
|
|
|
% Linear fit in the "linear" region
|
|
fit_l = polyfit(Ty(i_l_start:i_l_stop), thetay(i_l_start:i_l_stop), 1);
|
|
|
|
% Linear fit in the "mechanical stop" region
|
|
fit_s = polyfit(Ty(i_s_start:i_s_stop), thetay(i_s_start:i_s_stop), 1);
|
|
|
|
% Reset displacement more precisely based on fit
|
|
thetay = thetay - fit_l(2);
|
|
fit_s(2) = fit_s(2) - fit_l(2);
|
|
fit_l(2) = 0;
|
|
|
|
% Estimation of the bending stiffness and bending stroke
|
|
kRy(i) = 1/fit_l(1); % Bending Stiffness [Nm/rad]
|
|
kSy(i) = 1/fit_s(1); % Mechanical "Stop" Stiffness [Nm/rad]
|
|
Rmy(i) = fit_l(1)*fit_s(2)/(fit_l(1) - fit_s(1)); % Maximum angular stroke [rad]
|
|
|
|
if i == 1
|
|
plot(Ty(1:10:i_s_stop), 1e3*thetay(1:10:i_s_stop), '-', 'color', [colors(2,:), 0.4], ...
|
|
'DisplayName', '$k_{R_y}$')
|
|
else
|
|
plot(Ty(1:10:i_s_stop), 1e3*thetay(1:10:i_s_stop), '-', 'color', [colors(2,:), 0.4], ...
|
|
'HandleVisibility', 'off')
|
|
end
|
|
end
|
|
|
|
xlabel('Torque $T$ [Nm]');
|
|
ylabel('Angle $\theta$ [mrad]');
|
|
xlim([0, 0.15]);
|
|
ylim([-5,25]);
|
|
legend('location', 'southeast', 'FontSize', 8);
|
|
|
|
figure;
|
|
histogram([kRx, kRy], [4:0.2:5])
|
|
xlabel('Bending stiffness [Nm/rad]')
|
|
xticks([4:0.2:5])
|