Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 16 additions & 0 deletions toolbox/examples/friction_model/friction_RHS_filippov.m
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Add the paper this model was taken from as a source in a comment at the beginning (see pprhs.m for an example).

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Added

Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
function dx = friction_RHS_filippov(t, x, p)
% p = (k, m, mu_b, F_s, delta, epsilon)
k = p(1);
m = p(2);
mu_b = p(3);
F_s = p(4);
delta = p(5);
epsilon = p(6);
mu_rel = x(2) - mu_b;

dx = zeros(2,1);
dx(1) = x(2);

dx(2) = -(k / m) * x(1) + F_fric_fil(x, mu_rel, epsilon, F_s, k, delta) / m;

end
15 changes: 15 additions & 0 deletions toolbox/examples/friction_model/friction_RHS_no_filippov.m
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Add the paper this model was taken from as a source in a comment at the beginning (see pprhs.m for an example).

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Added to the main script as both variants are found in this same source.

Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
function dx = friction_RHS_no_filippov(t, x, p)
% p = (k, m, mu_b, F_s, delta, epsilon)
k = p(1);
m = p(2);
mu_b = p(3);
F_s = p(4);
delta = p(5);
epsilon = p(6);
mu_rel = x(2) - mu_b;

dx = zeros(2,1);
dx(1) = x(2);
dx(2) = -(k / m) * x(1) + F_fric_no_fil(x, mu_rel, epsilon, F_s, k, delta) / m;

end
219 changes: 219 additions & 0 deletions toolbox/examples/friction_model/friction_model_comparison.m
Original file line number Diff line number Diff line change
@@ -0,0 +1,219 @@
%% Source: Stick-Slip Vibrations Induced by Alternate Friction Models
% paper by: R. Leine, D. van Campen, A. de Kraker, and L. van den Steen
% doi: 10.1023/A:1008289604683

% The system describes dry friction of a spring suspended weight sitting on a
% constantly moving conveyor belt. The weight moves along with the belt
% until spring tension becomes too high and the weight is pushed back.
% This creates a switched periodic motion.

% The corresponding ODE can be formulated in a filippov and non-filippov
% variant and serves as a perfect example to test the accuracy of not only
% the filippov integration but also the resulting sensitivities.

% Both formulations can be found in "Numerical Solution of Optimal Control
% Problems with Explicit and Implicit Switches" by Andreas Meyer
% chapter: 15.3

integrator = @ode45;
t0 = 0;
tf = 30;
timeinterval = [t0,tf];
initstates = [1.133944669704 0 ];
p(1) = 1.0; %k
p(2) = 1.0; %m
p(3) = 0.2; %mu_b
p(4) = 1; %F_s
p(5) = 3; %delta
epsilon = 1e-11;
p(6) = epsilon; %epsilon

% saving current warning state for filippov detection (then turn off warning)
initial_filippov_warning_state = warning('query', 'IFDIFF:chattering').state;
warning('off', 'IFDIFF:chattering');
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should store the current state of the warning, so it can be restored to the same state later. See MATLAB documentation for temporarily disabling a warning.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done!


%% Solving the friction model variant without filippov mode
% preprocessing
fprintf('Preprocessing...\n ');
odeoptions = odeset( 'AbsTol', 1e-20, 'RelTol', 1e-6);
filename = 'friction_RHS_no_filippov';
dhandle = prepareDatahandleForIntegration(filename, 'integrator', integrator, 'options', odeoptions);
fprintf('Done, now integrate...\n');

% integrate
try
sol_no_filippov = solveODE(dhandle, timeinterval, initstates, p);
catch ME
warning(initial_filippov_warning_state, 'IFDIFF:chattering');
warning('Problem integrating model variant wihtout filippov behaviour...');
rethrow(ME);
end
fprintf('Done \n');

% results
T = t0:0.01:tf;
Y_no_fil = deval(sol_no_filippov, T);

figure(1); hold on; box on;

integrator_steps_marker_vals = zeros(length(sol_no_filippov.x));

plot(T, Y_no_fil(1,:), 'LineWidth', 2);
plot(T, Y_no_fil(2,:), 'LineWidth', 2);
plot(sol_no_filippov.x, integrator_steps_marker_vals, 'rx', 'MarkerSize', 8, 'LineWidth', 1, 'Color', [0, 0, 0.5]);
xline(sol_no_filippov.switches, '--r', 'LineWidth', 1.5);

xlabel('Time (s)', 'FontSize', 12);
ylabel('States', 'FontSize', 12);
title('ODE Solution to Friction Model', 'FontSize', 14);

legend({'Position of Weight','Velocity of Weight'}, 'Location', 'best');
grid on;

set(gca, 'FontSize', 12, 'LineWidth', 1.2);

%% Computing VDE-sensitivities

dim_y = size(sol_no_filippov.y, 1);
dim_p = length(p);
FDstep = generateFDstep(dim_y, dim_p);
integrator_options = odeset('AbsTol', 1e-14, 'RelTol', 1e-12);
try
sensitivities_function_VDE = generateSensitivityFunction(dhandle, sol_no_filippov, FDstep, 'integrator_options', integrator_options);
sens = sensitivities_function_VDE(T);
catch ME
warning(initial_filippov_warning_state, 'IFDIFF:chattering');
warning('Problem with sensitivities in model variant wihtout filippov behaviour...');
rethrow(ME)
end
Gy11 = arrayfun(@(x) x.Gy(1, 1), sens);
Gy12 = arrayfun(@(x) x.Gy(1, 2), sens);
Gy21 = arrayfun(@(x) x.Gy(2, 1), sens);
Gy22 = arrayfun(@(x) x.Gy(2, 2), sens);

figure(500); box on;

Gy = {Gy11, Gy12, Gy21, Gy22};
names = {'Gy11','Gy12','Gy21','Gy22'};

% plot the sensitivities w.r.t. the initial states
for k = 1:4
subplot(2,2,k)
hold on

scatter(T, Gy{k}, 'LineWidth',0.5,'Color',[0 0.5 0],'Marker','.')
plot(sol_no_filippov.x, integrator_steps_marker_vals, 'rx','MarkerSize',8,'LineWidth',1,'Color',[0 0 0.5])

xline(sol_no_filippov.switches,'--r','LineWidth',1.5);

xlabel('Time (s)','FontSize',12)
ylabel(names{k},'FontSize',12)
title(names{k},'FontSize',14)
legend(names{k},'Location','best')
grid on
set(gca,'FontSize',12,'LineWidth',1.2)
end


%% Solving the friction model variant with filippov mode
% preprocessing
fprintf('Preprocessing...\n ');
filenamefil = 'friction_RHS_filippov';
dhandle_filippov = prepareDatahandleForIntegration(filenamefil, 'integrator', integrator, 'options', odeoptions);
fprintf('Done, now integrate...\n');

% integrate
try
sol_filippov = solveODE(dhandle_filippov, timeinterval, initstates, p);
catch
warning(initial_filippov_warning_state, 'IFDIFF:chattering');
warning('Problem integrating model variant wiht filippov behaviour...');
rethrow(ME);
end
fprintf('Done \n');

% results
T = t0:0.01:tf;
Y_filippov = deval(sol_filippov, T);

figure(2); hold on; box on;

integrator_steps_marker_fil = zeros(length(sol_filippov.x));

plot(T, Y_filippov(1,:), 'LineWidth', 2);
plot(T, Y_filippov(2,:), 'LineWidth', 2);
plot(sol_filippov.x, integrator_steps_marker_fil, 'rx', 'MarkerSize', 8, 'LineWidth', 1, 'Color', [0, 0, 0.5]);

xline(sol_filippov.switches, '--r', 'LineWidth', 1.5);

xlabel('Time (s)', 'FontSize', 12);
ylabel('States', 'FontSize', 12);
title('ODE Solution to Friction Model (Filippov)', 'FontSize', 14);

legend({'Position of Weight','Velocity of Weight'}, 'Location', 'best');
grid on;

set(gca, 'FontSize', 12, 'LineWidth', 1.2);

%% Compute filippov sensitivities
% to do

%% creating difference plot

figure(3); hold on; box on;

integrator_steps_marker_fil = epsilon * ones(length(sol_filippov.x));
fildiff = abs(Y_filippov - Y_no_fil);

plot(T, fildiff(1,:), T, fildiff(2,:), 'LineWidth', 2);
plot(sol_filippov.x, integrator_steps_marker_fil, 'rx', 'MarkerSize', 8, 'LineWidth', 1, 'Color', [0, 0, 0.5]);

xline(sol_no_filippov.switches, '--r', 'LineWidth', 1.5);

xlabel('Time (s)', 'FontSize', 12);
ylabel('Difference', 'FontSize', 12);
title('Difference of filippov and non-filippov integrations', 'FontSize', 14);

legend({'Diff Position','Diff Velocity'}, 'Location', 'best');
grid on;

set(gca, 'FontSize', 12, 'LineWidth', 1.2, 'YScale', 'log');

%% Display of the switching functions

nu_rel = (Y_no_fil(2,:) - p(3));

figure(4);
subplot(2, 1, 1); hold on; box on;

scatter(T, nu_rel, 'LineWidth', 0.5, Marker='.');
plot(sol_filippov.x, 0, 'rx', 'MarkerSize', 8, 'LineWidth', 1, 'Color', [0, 0, 0.5]);

xline(sol_no_filippov.switches, '--r', 'LineWidth', 1.5);

xlabel('Time (s)', 'FontSize', 12);
ylabel('\nu_{rel} (switching function)', 'FontSize', 12);
title('Evolution of first switching condition', 'FontSize', 14);

legend({'\nu_{rel}'}, 'Location', 'best');
grid on;

set(gca, 'FontSize', 12, 'LineWidth', 1.2);

subplot(2, 1, 2); hold on; box on;

scatter(T, nu_rel, 'LineWidth', 0.5, Marker='.');
plot(sol_filippov.x, 0, 'rx', 'MarkerSize', 8, 'LineWidth', 1, 'Color', [0, 0, 0.5]);

xline(sol_no_filippov.switches, '--r', 'LineWidth', 1.5);

xlabel('Time (s)', 'FontSize', 12);
ylabel('\nu_{rel} (switching function)', 'FontSize', 12);
title('Evolution of first switching condition', 'FontSize', 14);
ylim([-2 * epsilon 2 * epsilon]);
legend({'\nu_{rel}'}, 'Location', 'best');
grid on;
set(gca, 'FontSize', 12, 'LineWidth', 1.2);

% return warining state to what it was before running the code
warning(initial_filippov_warning_state, 'IFDIFF:chattering');
8 changes: 8 additions & 0 deletions toolbox/examples/friction_model/helpers/F_fric_fil.m
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
function res = F_fric_fil(x, mu_rel, epsilon, F_s, k, delta)
if mu_rel <= 0
res = F_s / (1 - delta * mu_rel);
else
res = -F_s / (1 + delta * mu_rel);
end
end

20 changes: 20 additions & 0 deletions toolbox/examples/friction_model/helpers/F_fric_no_fil.m
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
function res = F_fric_no_fil(x, mu_rel, epsilon, F_s, k, delta)
if mu_rel <= -epsilon
res = F_s / (1 - delta * mu_rel);
else
if mu_rel >= epsilon
res = (-F_s) / (1 + delta * mu_rel);
else
if k*x(1) <= -F_s
res = F_s;
else
if k*x(1) >= F_s
res = F_s;
else
res = k*x(1);
end
end
end
end
end