I am building a circuit model for a transformer which models the effects of hysteresis. It does so using the Matlab function block on the right, and works successfully when tested in isolation. However, the value of the magnetising inductance Lm depends on calculations requiring the value of Im. But Simulink cannot determine the value of Im without the value of Lm, thus forming an algebraic loop.
However, I have the initial value for the inductance, Lm_initial loaded into the workspace. With this, I should be able to solve for the first Im value, which can be used to determine the next Lm, and so on. However, specifying Lm_initial in the variable inductor's properties doesn't work; Simulink tries to evaluate Lm with the nonexistent 'phi' and 'Im' values rather than trying to solve for an initial Im using the value of the initial inductance.
I have tried solutions involving commenting/uncommenting blocks and implementing further subsystems which activate/deactivate depending on the time step, as well as unit delays, but these run into issues regarding tracking time for calculating the derivatives or output very incorrect/noisy waveforms.
Is there a relatively simple solution for this case? The problem appears as if it'd be relatively simple to solve, but I cannot seem to find a workaround for this.
Transformer Equivalent Model
The exact placement of the unit delay in the loop might be the key here: try to place the unit delay between the [lm] GoTo block and the lm input of your MATLAB function block fcn, that should work. And set the initial condition parameter to Lm_initial.
Related
Initialization could be very cumbersome and easily lead to divergence. A simple strategy is to run the simulation when building a part of the whole system and use the simulation results to modify guess values.
Here is what I got in the PPT from Francesco Casella and the book from Daniel Bouskela.
I found that I could use an option in Dymola as follows, but instead of using the initialization result, I wanna use the result when reaching a steady state. So I'd like to use a python script to extract the result from the .mat result file, then modify the iteration variables automatically. But the key problem is that I don't know when I add more components in my model, the iteration variable set of existing components would change, I don't know what kind of effect would this causes.
Anyone got opinion on this issue, welcome to answer this question.
So my question is where should I find the python
You can use the end values (= steady state) of the simulation result in order to create a new initialization (Dymola Manual 1, section 2.5.12) . If the component names are the same in the sub system model and the total model, you can run the script created in the subsystem model on the larger system model as well. But you have to check if your models have initial equations that hinder an initialization from the outside (see section 4.2 in https://2012.international.conference.modelica.org/proceedings/html/pdf/ecp12076927_KruegerMehlhaseSchmitz.pdf)
It should also be possible to initialize it steady state. Instead of providing initial values for a state x and fixing it, you can provide initial equations for the derivatives such as der(x) = 0;
With that setup activate Save Initial Results and you should be good to go.
I've developed a controller in Simulink and am trying to export it as a pure C class using Simulink coder for deployment on our microcontroller. We are using a fixed step solver in simulation, however, when the exported code gets used on our actual plant, the actual step size may change depending on load of the processor.
My concern is this: say I have set the fixed time step as 0.05s in simulation (and therefore the exported code assumes it is being executed every 0.05s), but then the microprocessor sometimes executes after 0.1s, and sometimes after 0.03s, etc. I think this would cause some unwanted behaviour.
Is there a way to have Simulink coder create a variable for step-time that we can adjust during run time? That is, measure how long it has been since the last execution, and then fill in the variable during each execution.
For an analogy, in videogame programming the update functions usually include a dt parameter so we know how long its been since the last frame.
The only solution I can find is to manually search and replace the step size in all the integrator blocks after the code has been generated. This, however, seems error prone.
I'm trying to build a system in Simulink, but I get errors about Algebraic Loops.
Could you please help?
The goal of this system is to observe behaviour of double pendulum with a spring attached to the lower part of it.
Here's my system: http://1drv.ms/1GPqeeQ
I can't post pictures, because i don't have enough points on StackOverflow.
Yep it's common problem.
The problem is that simulink try to use variable value to calculate itself (at one step).
You can solve this problem easily - you just need to add Unit Delay block for this variable. Like this:
You can see I use variable Vd to calculate itself again at every step.
I added Unit Delay and simulink use the value of Vd from PREVIOUS STEP!
It works perfectly!
My initial problem is that I have a continuous transfer function which coefficients change with time.
Currently the TF's coefficients are expressed in function of the block mask parameters. These parameters are tunable, and if I change the value in the mask parameters dialog during a simulation the response seems to react appropriately.
However how can I do just that in the code/block flow? Basically, I
have the block parameter 'maskParam' which is set using the mask
parameters dialog, and in the mask initialization commands:
'param=maskParam'. 'param' is used in the transfer function and I
would like to change it in real time (as param=maskParam*f(t)).
I have already looked around and found relevant solutions but either it's unbelievably complicated; or the only transfer function which we are allowed to modify at runtime is discrete and 1) I would like to avoid z-transforming my quite complex TF (I don't have the control toolbox) 2) The sampling time seems to be fixed.. None uses this "dirty" technique of updating parameters, maybe that's the way around?
To illustrate:
I am assuming that you want to change your sim parameters whilst the simulation is running?
A solution is that you run your simulation for inf period and use/change a workspace variable during the simulation period to make the changes take effect.
for Example:
If you look at the w block, you can set it's value in runtime, by doing this:
set_param('my_model_name/w', 'value', 100); % Will change to 100 immediately
You can do similar things with arrays (i.e. a list of coefficients in your case).
HINT FOR YOU
You are using discrete transfer function block. Try the following:
1) Give your block a name e.g. fcn_1
2) In your script, type set_param('your_model_name/fcn_1', 'numerator', '[1 2]'); This will set the numerator value to [1 2]. Do the same for denominator.
3) You should be able to understand, through this exercise, how to handle the property names etc. so that you can change/get them using set_param/get_param.
I leave you to investigate further.
The short answer is that Simulink blocks are not really designed to do this. By definition, a transfer function is Liner-Time Invariant, meaning its characteristics (read coefficients) do not vary with time.
Having said that, there are some workarounds, such as the ones you mentioned in your question. These are the correct way to approach the problem I'm afraid, other than the set_param method suggested by #ha9u63ar. See also this blog on the subject on the MathWorks web site.
I have 2 embedded Matlab functions which I am using to create a Simulink model. Both functions use the output of the second function as their input. I am getting an error at the moment indicating that this is an invalid loop.
Does anyone know how to implement this type of behaviour?
You've created an algebraic loop, which means that to compute the inputs of the Embedded MATLAB block are directly dependent on the outputs of the block. This is not allowed when the loop is a "self-loop", i.e. there is only one block in the loop.
One way to fix this is to put Unit Delay block(s) somewhere on the signal feeding back into the Embedded MATLAB block. See the documentation on algebraic loops for more information.