Combine lsqcurvefit with fsolve
1 vue (au cours des 30 derniers jours)
Afficher commentaires plus anciens
Gregory Cottone
le 1 Avr 2021
Commenté : Gregory Cottone
le 4 Avr 2021
Hi,
my goal is to optimize the length L0, L1, L2 and L3 of the bars of the following mechanism so that the theta2 angle follows the trend of my input data:
This is the mechanism:
And this is the data that I want to fit:
theta1 = linspace(0,pi,n);
theta2 = [0.53,0.40,0.32,0.28,0.27,0.27,0.28,0.29,0.31,0.34,0.36,0.40,0.43,0.47,0.50,0.55,0.59,0.64,0.69,0.75]; %(data to fit)
which they have this trend:
My strategy was to mainly use the lsqcurvefit function and have the kinematic closure equation solved recursively using the fsolve function:
clc;
clear all;
n = 20;
theta1 = linspace(0,pi,n);
theta2 = [0.53,0.40,0.32,0.28,0.27,0.27,0.28,0.29,0.31,0.34,0.36,0.40,0.43,0.47,0.50,0.55,0.59,0.64,0.69,0.75]; %(data to fit)
L0 = [0,0,0,0]; % Initial lenght of the bars, in the order: L0,L1,L2 and L3
for i = 1:n
y0 = [0.5,1.1]; % Initial guess of theta2 and theta3
options = optimset('display', 'off');
y(i,:) = fsolve(@(y)fourbar(y,theta1(i)),y0,options);
end
%Objective: find the L0, L1, L2 and L3 optimized to make the function...
...interpolating the data (theta1,theta2)
L = lsqcurvefit(@fourbar,L0,theta1,theta2);
function Phi = fourbar(y,L,theta1)
u1 = [cos(theta1), sin(theta1)];
u2 = [cos(y(1)), sin(y(1))];
u3 = [cos(y(2)), sin(y(2))];
Phi = L(1)*u1 + L(2)*u2 - L(3)*u3 - [L(4), 0];
end
But unfortunately it doesn't work and I don't know how to solve the problem.
4 commentaires
Réponse acceptée
Matt J
le 3 Avr 2021
Modifié(e) : Matt J
le 3 Avr 2021
I would just use lsqnonlin.
theta2 = [0.53,0.40,0.32,0.28,0.27,0.27,0.28,0.29,0.31,0.34,0.36,0.40,0.43,0.47,0.50,0.55,0.59,0.64,0.69,0.75]; %(data to fit)
theta1 = linspace(0,pi,numel(theta2));
L0=1;
opts=optimoptions(@lsqnonlin,'StepTolerance',1e-12,'OptimalityTolerance',1e-12,'FunctionTolerance',1e-12);
[L,resn,res]=lsqnonlin(@(L) resid(L,L0,theta1,theta2), [0.5,0.5,1]*L0, [0,0,0],[1,inf inf]*L0);
L
function fval=resid(L,L0,theta1,theta2)
dX=L(1)*cos(theta1(:))+L(2)*cos(theta2(:));
dY=L(1)*sin(theta1(:))+L(2)*sin(theta2(:));
fval=(L0-dX).^2 + dY.^2-L(3).^2;
end
Plus de réponses (0)
Voir également
Produits
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!