Function 'syms' not supported for code generation.
45 views (last 30 days)
Show older comments
Hello
I am trying to implement the following function into a matlab function in simulink. When i run the function in matlab it works perfectly well, but when i run it in simulink i get the error "Function 'syms' not supported for code generation." Can anyone please help me how to implement this function in simulink? thank you in advance.
function theta_y2 = geoy2SL(SL)
%Denne funktion beregnner yderled 2's position som funktion af stemplets
%slaglængde
% input er stemplets slaglængde, output er bommens position
syms theta_y2
%Målepunkter fra cad model
p0_y2 = [0;0]; %punkt 0 [m]
p1_y2 = [19.1816*10^(-3);-68.7660*10^(-3)]; %punkt 1 [m]
p2_y2 = [29.4079*10^(-3);-227.950*10^(-3)]; %punkt 2 [m]
p3_y2 = [-245.761*10^(-3);-114.832*10^(-3)];%punkt 3 [m]
p4_y2 = [214.428*10^(-3);-108.923*10^(-3)]; %punkt 4 [m]
p5_y2 = [806.212*10^(-3);-106.555*10^(-3)]; %punkt 5 [m]
%Beregning af længer på led
r_a_y2=sqrt(sum((p1_y2-p0_y2).^2)); %led a [m]
r_b_y2=sqrt(sum((p2_y2-p1_y2).^2)); %led b [m]
r_c_y2=sqrt(sum((p3_y2-p2_y2).^2)); %led c [m]
r_d_y2=sqrt(sum((p3_y2-p0_y2).^2)); %led d [m]
r_e_y2=sqrt(sum((p4_y2-p2_y2).^2)); %led d [m]
r_f_y2=sqrt(sum(p5_y2.^2)); %led f [m]
r_g0_y2=sqrt(sum((p5_y2-p4_y2).^2));
%Kendte vinkler i geometrien beregnes ift. den positive x-akse,
%ved bommens udgangsposition som er helt udfoldet:
theta_a0y2=asin((p1_y2(2)-p0_y2(2))/r_a_y2); %vinkel a i udgangsposition [rad]
theta_ay2=theta_a0y2+theta_y2; %vinkel a variabel [rad]
theta_c0y2=atan((p3_y2(2)-p2_y2(2))/(p3_y2(1)-p2_y2(1)));
theta_d0y2=atan2((p3_y2(2)-p0_y2(2)),(p3_y2(1)-p0_y2(1))); %vinkel d i udgangsposition [rad]
theta_e0y2=atan2((p4_y2(2)-p2_y2(2)),(p4_y2(1)-p2_y2(1))); %vinkel e i udgangsposition [rad]
theta_f0y2=asin((p5_y2(2)-p0_y2(2))/r_f_y2); %vinkel f i udgangsposition [rad]
theta_fy2=theta_f0y2+theta_y2; %vinkel f variabel [rad]
%Den variable vinkel i 4 leds geometrien defineres ud fra kendte vinkeler:
theta_2y2=-(theta_d0y2-theta_a0y2)+theta_y2; %vinkel 2 variabel [rad]
%længden af linjestykkerne r, s og t beregnes
r_y2=r_d_y2-r_a_y2*cos(theta_2y2); %længde linje r [m]
s_y2=r_a_y2*sin(theta_2y2); %længde linje s [m]
t_y2=sqrt(r_a_y2^2+r_d_y2^2-2*r_a_y2*r_d_y2*cos(theta_2y2));%længde linje t [m]
%Beregning af vinklen delta
delta_y2=acos((r_b_y2^2+r_c_y2^2-t_y2.^2)/(2*r_b_y2*r_c_y2));%vinkel delta variabel [rad]
%Beregning af længden af linjestykkerne p og q
p_y2=r_b_y2-r_c_y2*cos(delta_y2); %længde linje p [m]
q_y2=r_c_y2*sin(delta_y2); %længde linje q [m]
%beregning af vinklen theta_3y1:
theta_3y2=atan2((q_y2.*r_y2-p_y2.*s_y2),(p_y2.*r_y2+q_y2.*s_y2)); %variable vinkel 3 [rad]
%Beregning af vinklen theta_4y1
theta_4y2=delta_y2+theta_3y2; %variable vinkel 4 [rad]
%Beregning vinkel theta_by1:
theta_by2=theta_d0y2+theta_3y2; %variable vinkel b [rad]
%Beregning vinkel theta_cy1:
theta_cy2=theta_d0y2+theta_4y2; %variable vinkel c [rad]
%beregning af konstant vinkel mellem linje c og e:
theta_cey2=pi-(abs(theta_e0y2)+abs(theta_c0y2)); %vinkel ml. linje e og c [rad]
%beregning af vinkel theta_ey1:
theta_ey2=pi-(theta_cey2-theta_cy2); %variable vinkel e [rad]
%definition af vektorerne a, b, e, f:
va_y2=r_a_y2*[cos(theta_ay2);sin(theta_ay2)]; %vektor a [m]
vb_y2=r_b_y2*[cos(theta_by2);sin(theta_by2)]; %vektor b [m]
vc_y2=r_c_y2*[cos(theta_cy2);sin(theta_cy2)]; %vektor c [m]
vd_y2=r_d_y2*[cos(theta_d0y2);sin(theta_d0y2)]; %vektor d [m]
ve_y2=r_e_y2*[cos(theta_ey2);sin(theta_ey2)]; %vektor e [m]
vf_y2=r_f_y2*[cos(theta_fy2);sin(theta_fy2)]; %vektor f [m]
%Beregning af vektor g, vha. ovenstående vektorer
vg_y2=vd_y2+vc_y2+ve_y2-vf_y2; %vektor g [m]
%længde af vektor g som funktion af bommens position:
r_g_y2=sqrt(sum(vg_y2.^2)); %længde linje g [m]
%Vinkel mellem positiv x-akse og vektor g beregnes
theta_gy2=atan2(vg_y2(2),vg_y2(1));
%Slaglængde som funktion af bommens position beregnes ud fra ændringen i
%vektor g's længde som funktion af bommens position
sl_y2=r_g_y2-r_g0_y2;
eqn=SL==sl_y2;
theta_y2=vpasolve(eqn,theta_y2);
end
0 Comments
Answers (2)
Charan Jadigam
on 12 Mar 2020
Hi,
To use ‘syms’ function in Simulink we have to place the symbolic declarations and operations in a separate .m file and call that function from MATLAB function block as extrinsic function. For example, create a new .m file as,
function output= Syms_in_sumulink(input)
syms x y
f = x*y + x* y^2;
output = subs (f, x, in);
end
and call this file from MATLAB function block as
coder. extrinsic(' Syms_in_sumulink ');
out = Syms_in_sumulink (in);
1 Comment
Walter Roberson
on 12 Mar 2020
This solution is only available if rapid acceleration is turned off or is at the lowest setting above off. In every other case of rapid acceleration the code generation needed does not have a backing MATLAB execution engine that is needed to execute anything inside the symbolic toolbox. The symbolic toolbox is implemented as its own process, running code that has a remote call protocol but otherwise cannot be directly accessed from MATLAB. Much of the symbolic toolbox is implemented in its own programming language that is not C or C++ and for which C/C++ code cannot be generated.
Do not think of the symbolic toolbox as a series of functions inside a DLL that could be linked to for specific tasks. There is, for example, no ability for MATLAB to call directly into a symbolic addition function, only an interface to remote call to the symbolic engine process and ask it to do the addition. The public interface between the two is entirely by character vector. (There are some mysterious undocumented routines that have unknown implementation.)
Which is to say that unless you are willing to restrict yourself to the minimum acceleration, you cannot use the symbolic toolbox with Simulink.
Walter Roberson
on 12 Mar 2020
For reasons I describe in my comments, if you want to be able to do rapid acceleration, or deploy to hardware, or use Simulink Coder to generate C or C++ code, then you will need to get rid of the symbolic toolbox usage.
In the case of the above code, it means taking all the code that uses the symbolic variable (or expressions derived from it) and turn them into anonymous functions. Then fzero or fsolve on the left side of the equation minus the right side, all expressed as an anonymous function making function calls
fzero(@(T) left(T) - right(T), initial guess)
3 Comments
Walter Roberson
on 29 Jan 2023
It is common that symbolic problems can be divided up into two phases: setting up the expressions, and calculating the value of the expressions with specific inputs.
The symbolic expressions can often be set up ahead of time in a seperate session, using symbolic variables in the place of the specific numeric values. Then you use matlabFunction() to convert the expressions into executable numeric MATLAB code that will accept (numeric) parameters and calculate appropriate results. You would tell matlabFunction() to write the function to a file.
Afterwards in the deployment phase, you would use code that did not bother trying to set up the expressions, but instead just gathered appropriate inputs -- and then called upon the already-generated code to perform the calculations.
Sometimes this just does not work out well enough and you can be stuck. There are expressions that MATLAB does fine solving for any given numeric coefficients, but for whatever reason it cannot proceed given a symbolic expression. Or sometimes the general symbolic route is just too expensive in practice -- for example symbolic eigenvalues for a 4 x 4 matrix can be calculated exactly (provided the case is not degenerate) but the resulting expressions would be rather long and that approach would probably not be used in practice except to prove a point.
See Also
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!