How can I calculate block parameters from mask parameters?

The Goal:
I have a subsystem which I now want to control over a mask. The mask should allow me to chose between two materials and give a thickness and radius of a cylinder. In the subsystem I then want to use the material choice to define the relevant material parameters (e.g. in a "if material == 1, then parameters =... " statement) and I want to pass on the thickness and radius, however they are not direct parameters for a block in the code (so I can't just promote them). Instead I want to do calculations with them, e.g. I have an impedance that calculates from Z=rho*pi*r^2. Rho should be defined by the Material choice and r should be given in the mask in an edit block. See below for what I picture for the mask:
Now what I need to calculate from these is some further values. Before I created the subsystem I did this in the InitFunc of the model.
What I have currently:
classdef piezoElement_mask
methods(Static)
% Following properties of 'maskInitContext' are available to use:
% - BlockHandle
% - MaskObject
% - MaskWorkspace: Use get/set APIs to work with mask workspace.
function MaskInitialization(~)
end
% Use the code browser on the left to add the callbacks.
function material(mat)
if isequal(mat, 1)
g33=0.0142188;
g31=-0.0333414;
c33D=1.362e11;
c11D=7.268e10;
h33=g33*c33D;
h31=g31*c11D;
eps33S=9.249e-9;
rho=14672.908;
end
if isequal(mat,2)
c33D=1.295e11;
c11D=8.587e10;
h33=1.302e9;
h31=-1.684e9;
eps33S=8.711e-9;
rho=17435.538;
end
end
function thickness(th)
d = th*1e-3;
end
function radius(rd)
r = rd*1e-3;
A=pi*r^2;
C0=A*eps33S/d;
Z33 = A*sqrt(c33D/rho)*rho;
t33=d/sqrt(c33D/rho) ;
Z11 = 2*pi*d*r*sqrt(c11D/rho)*rho;
t11=2*r/sqrt(c11D/rho) ;
end
end
end
There's probably a better way to do this, also this right now doesn't work. I always get an error for thickness and radius (material seems to be fine?) and my blocks in the subsystem still use the parameters stored in the MATLAB variable browser, not the updated values I try to give here.
Can anyone help? I've found loads of information on passing on parameters, but only for when you use the parameter directly and not if you want to use them for calculations first.

 Respuesta aceptada

Angelo Yeo
Angelo Yeo el 22 de Nov. de 2023
Editada: Angelo Yeo el 22 de Nov. de 2023
If you were to choose one our of multiple scenarios depending on your choices, a good way to go is to use a variant subsystem with masking. The example below can be of your help.

8 comentarios

Thanks for your answer. A variant subsystem could be an option for the choice between two materials, but that still doesn't answer the more difficult question of how I can do math with a mask edit parameter before passing the result on to a block in the subsystem.
What I need is a parameter "radius" in my mask, which I can set to any real number. Then I want to do calculations with it for multiple parameters in different blocks, e.g. A=pi*r^2, Z=A*rho, t = c/r,... and pass those resulting values on to the blocks.
How can I access the number values in the mask's edit parameters? What data type is rad if I access the mask parameter using
function radius(rad)
r=rad*1e-3;
end
in the Initialization code? How can I get the number value that I can do further calculations with? How do I pass mask parameters to blocks outside of parameter promotion? Is there any way to see which variables are stored in the local subsystem library?
I don't understand your pain point. Can you share your model and tell me how to reproduce your issue?
Please see my other comment, I seem to have accidentally put it in the wrong answer box.
I think I found the point. You should understand that Simulink masks use a separate workspace. In order to assign the variables into base workspace, you can use assignin function. Please take a look at the attached demo where you assign variables into baseworkspace according to your choice of mask parameters. In the demo, selecting a radio button creates different testVal in the base workspace.
Hey Angelo, thank you for the Demo! It helped me create a working mask which now finally manages to update the global variables.
However, I am still encountering problems. Are there different syntax/math rules for mask initialization code? Part of my code is the following:
function rad(~)
radius = get_param(gcbh, 'rad');
disp(radius)
disp(radius-48)
assignin('base', 'r', radius*0.001);
end
Lets say I input radius as 3 in the mask. Disp(radius) then gives me 3. But disp(radius-48) also gives me 3 (this does not happen for other numbers, 48 seems to be THE number I have to substract to get the number I already shoud have). I am VERY confused. radius*0.001 makes 0.051 even though it should be 0.003. If I calculate (radius-48)*0.001 I get 0.003. This is not how math works, what is happening????
Thank you for all your help and all your patience with me.
Annika Michel
Annika Michel el 23 de Nov. de 2023
Editada: Voss el 30 de Oct. de 2024
Also, putting in a decimal (2.5) lead to [2 -2 5] if I calculated disp(radius-48). It's making an array now, even though just disp(radius) shows me 2.5.
I feel like I broke Math. What the [redacted] is happening...
Thank you Annika for your reply. I'm glad you made some progress :D
BLOT: Change the code like below.
function rad(~)
radius = get_param(gcbh, 'rad');
radius = str2double(radius); % Add this %
disp(radius)
disp(radius-48)
assignin('base', 'r', radius*0.001);
end
Note that the variable radius is a character variable. I believe you must have taken this value from "Edit" field. Characters are basically numbers and mapped by ASCII rule. So, MATLAB dynamically mapped back the character into original number. For example, the character 'A', 'B', 'C' are mapped from 65, 66, 65 respectively.
double('A')
ans = 65
double('B')
ans = 66
double('C')
ans = 67
Accordingly, the character '3' is mapped from is mapped from 51.
double('3')
ans = 51
That's why you would get the result 3 when you calculated '3' - 48.
'3'-48
ans = 3
Same story for '2.5'. Let's see how '2', '.', '5' are mapped from 50, 46, 53 in ASCII respectively.
double('2.5')
ans = 1×3
50 46 53
So that's why
'2.5' - 48
ans = 1×3
2 -2 5
So, the solution is to use str2double. This will change characters into the number (not mapping back to numbers based on ASCII rule).
Thank you, that fixed it!
Thanks again for everything!

Iniciar sesión para comentar.

Más respuestas (1)

Annika Michel
Annika Michel el 22 de Nov. de 2023
I've attached the model, subsystem and subsystem mask. In the Model (Galliere_neg_Kond_V16_TEW_ref_bauteil) you will find a bunch of calculations in the InitFcn. The first half of those I would like to do within the referenced subsystem, but haven't found a way to do so yet. If you look at the subsystem (PiezoElement) you will find that all block parameters within are variables, which currently are defined in the Model's InitFcn. However, I would like to contain those variables within the subsystem by creating a system mask. The system mask would allow me to chose between two materials (second material is currently not within the Model InitFcn, but would work equivalent with different values) and give decimal values for radius and thickness. With the material parameters and radius and thickness I want to then calculate the variables given into the subsystem blocks. Again, this should all happen within the subsystem. The model should only see the mask.
The subsystem mask (piezoElement_mask) is my attempt to execute calculations with the mask input parameters. However, the variables I define within the mask code do not overwrite the subsystem variables and do not get passed on to the subsystem blocks.
What I want:
1) Subsystem is in Model. Model shows subsystem Mask. Mask contains Material choice (1 or 2), radius (edit field, numerical), thickness (edit field, numerical)
2) Subsystem recieves (e.g.) Material =1; radius = 3; thickness =5.
3) Subsystem goes through calculations and definitions: If material is =1, then Material parameters are defined according to list 1. Radius and Thickness and material parameters are used in several calculations for 9 different block parameters.
4) Subsystem passes calculation results on to blocks.
I'm having trouble with 2->3 and 3->4, basically I don't know how to access the mask parameters and do things with them.

1 comentario

Oh and for the Model to run you need to define freqHz in the console. A good value is freqHz=280000

Iniciar sesión para comentar.

Categorías

Productos

Versión

R2023b

Preguntada:

el 21 de Nov. de 2023

Editada:

el 30 de Oct. de 2024

Community Treasure Hunt

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

Start Hunting!

Translated by