MATLAB Answers

Function 'syms' not supported for code generation.

95 views (last 30 days)
Daniel Hansen
Daniel Hansen on 8 Nov 2019
Answered: Walter Roberson on 12 Mar 2020
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
% 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]
%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_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
%Slaglængde som funktion af bommens position beregnes ud fra ændringen i
%vektor g's længde som funktion af bommens position

Answers (2)

Charan Jadigam
Charan Jadigam on 12 Mar 2020
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);
and call this file from MATLAB function block as
coder. extrinsic(' Syms_in_sumulink ');
out = Syms_in_sumulink (in);
You can know more about extrinsic functions here.
  1 Comment
Walter Roberson
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.

Sign in to comment.

Walter Roberson
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)




Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!

Translated by