I essentially have a 28-parameter non-linear equation. when f(x) = 0
, I can measure 14 parameters and I have data to generate 133 equations with the varying 14 measured parameters. I now need to find the values of the 14 unknown parameters (unconstrained) that result in the minimum residual.
I believe the MATLAB optimization toolbox (fsolve
) should do the job. My objective function is a product of 3 transformation matrices and hence quite long and not explicitly written.
function fRMS= MyObjectiveFunction(xi)
syms sx sy aa bb cc ro tau omega x y z alpha beta gamma
xi = [ sx, sy, aa, bb, cc, ro, tau, omega, x,y,z, alpha, beta, gamma];
load CalibData.mat n1 n2 n3 n4 n5 n6 n7 n8 n9 t1 t2 t3 u v
rTp=[cos(omega)*cos(tau) cos(omega)*sin(tau)*sin(ro)-sin(omega)*cos(ro) cos(omega)*sin(tau)*cos(ro)+sin(omega)*sin(ro) aa;...
sin(omega)*cos(tau) sin(omega)*sin(tau)*sin(ro)+cos(omega)*cos(ro) sin(omega)*sin(tau)*cos(ro)-cos(omega)*sin(ro) bb;...
-sin(tau) cos(tau)*sin(ro) cos(tau)*cos(ro) cc;...
0 0 0 1];
cTt=[cos(alpha)*cos(beta) cos(alpha)*sin(beta)*sin(gamma)-sin(alpha)*cos(gamma) cos(alpha)*sin (beta)*cos(gamma)+sin(alpha)*sin(gamma) x;...
sin(alpha)*cos(beta) sin(alpha)*sin(beta)*sin(gamma)+cos(alpha)*cos(gamma) sin(alpha)*sin(beta)*cos(gamma)-cos(alpha)*sin(gamma) y;...
-sin(beta) cos(beta)*sin(gamma) cos(beta)*cos(gamma) z; 0 0 0 1]; % (labspace to bucket space)
for frame=1:133 % 133 frames
tTr(:,:,frame)=[n1(frame) n2(frame) n3(frame) t1(frame); n4(frame) n5(frame) n6(frame) t2 (frame); n7(frame) n8(frame) n9(frame) t3(frame); 0 0 0 1];
Px(:,frame)=[sx*u(frame); sy*v(frame); 0; 1];
Cx(:,frame)= cTt*tTr(:,:,frame)*rTp*Px(:,frame);
f(frame)= Cx(3,frame); % Z=0
end
fRMS=rms(f); % Objective function
When using the optimization toolbox, I get the following error. It may be as a result of how I pass a value to a symbolic variables. I would be very grateful for your help in resolving the error or offering an alternative approach to this problem.
Error using mupadmex
Error in MuPAD command: DOUBLE cannot convert the input expression into a double array.
If the input expression contains a symbolic variable, use the VPA function instead.
Many thanks!!