Using Simulink signal as a function variable (Real time Control System)

I am working with an existing model of a brushless DC motor in order to simulate a control system I want to use on an actual motor. I have modeled a Fuzzy Logic controller that uses the error and change in error in order to actively tune the Proportional and Integral gains of the PI-controller, which is already built into the motor model I have. My problem is that the model I am using defines the P and I gains as constants within an S-function that runs as part of the simulation, whereas I would like input my tuned gains (which are constantly updating based on the simulation progression) in real-time.
I was originally saving the gain values to variables in the workspace, but these do not update until the end of the sim, and therefore are not helpful. I would like to be able to call these updated gains into the control function of the system in real time. Is this possible to do with the existing model? I realize that the 'best' approach would normally be to re-make my own model and use the gains as input signals in the system. However, as this is merely for simulation purposes, it is not worthwhile for me to spend time doing this - I merely would like it as a proof-of-concept.

Antworten (2)

Ryan G
Ryan G am 17 Jul. 2012
Bearbeitet: Ryan G am 17 Jul. 2012

2 Stimmen

You need to make sure the P and I gains are Tunable Parameters in the s-function. Based on what you have already written about your issue it sounds like they are not tunable.

7 Kommentare

Thanks for the speedy reply, I believe your advice is in the right direction. The parameters that I am working with are specified in a Subsystem Mask prompt, much like a normal Gain (which is tune-able).
My previous approach was to simply input variables for these P & I gain values, and then retrieve them from my controller output. However, I got stuck at updating these variables in real-time.
I feel like this is possible (and seems like it would be easier/faster than editing all of the s-function code), but I haven't found a solution that allows this yet. Do you think this is feasible?
If the parameters are in fact tunable then you can use something like the following in a MATLAB function/Embedded MATLAB function block:
function y = fcn(u)
%#codegen
coder.extrinsic('assignin')
coder.extrinsic('set_param')
coder.extrinsic('num2str')
assignin('base','A',u);
set_param('untitled/Constant','Value','A')
y = u;
In this example I am updating a Constant block's value with the parameter in the base workspace. The input to the EML block for you would be the P and I gains and you would use set_param on your s-function block.
Will
Will am 17 Jul. 2012
Bearbeitet: Will am 17 Jul. 2012
Getting close! However, even using set_param, the value of the gain itself is not being reset until the end of the simulation if I am assigning the output of my FL Controller as a workspace variable. Do you know what I need to output it as in order to have it be updated continuously along with the simulation?
Thank you for the continued help!
The first thing you should do is test the functionality with something simple like a constant block. If that works it may be an issue with the tunability of the parameter in the s-function. One way to test this is set the time in the simulation to inf and attempt to open and manually change this parameter. If that does not work it is not tunable.
Will
Will am 17 Jul. 2012
Bearbeitet: Will am 17 Jul. 2012
Both can be assigned tunable or not-tunable within the Subsystem mask, and both are set to tunable*. If, for example, I say set_param('Model', 'P', 'KP') to set the P gain as variable KP, isn't this still referencing the workspace, and therefore not updated except at the start of the simulation? Ideally, is there a simple way for the output of my controller to update this parameter continuously?
If you look at the script for the EML I wrote you see I utilize assignin. This updates the base workspace parameter. After that the set_param function is essentially triggering the block, in this case an s-function, to determine that it has updated the parameter and will re-check the workspace for that parameter and update accordingly.
How is it that the parameter is being updated from the signal in this case? I guess more generally, what sort of sink do I need for the output of my controller so that the output is assigned to the variable 'A'?

Melden Sie sich an, um zu kommentieren.

Will
Will am 17 Jul. 2012
Bearbeitet: Will am 17 Jul. 2012

0 Stimmen

I've found some partial answers to my question, although it doesn't seem to address my individual case. In any event, they are posted below in the hopes that others may find it useful.
I also found a temporary workaround, although it's somewhat sloppy and greatly slows the simulation speed. I've added a set_param('model','SimulationCommand','update') line into my s-function code. The output signals from my controller are being written to workspace variables, and the line of code above forces the model to update each time around. As I said, somewhat sloppy, and it increases the simulation time by about 100x, so I'm continuing to look for other methods.

4 Kommentare

I think what you really want is additional input into the s-function for your parameter. If you have control of the s-function you can make these parameters inputs instead of dialog parameters and attach the signals directly. This would greatly improve simulation speed versus updating the Dialog Parameter.
What you are describing is what I had originally intended to do, but I did not understand how the model I am using was interpreting the inputs.
The inputs of the subsystem are fed combined in a mux then fed into the s-function block, but I can't see within the actual s-function .m file where they are being called. The function within the m-file that call the gains is as follows:
function sys=mdlOutputs(t,x,u,J,DF,BM,Rr,Rl,delta,KP,KI,KD,basecurr)
sys(4)=u(3)-u(1);
Treq = sys(4)*(KP + KI*0.5*4e-6) + u(4)*(KI*0.5*4e-6);
From here it computes the necessary output. I guess I'm confused at this point as to how I create the additional input for the function rather instead of another parameter.
Thank you again for all of your insight, it's been very helpful and is greatly appreciated!
If u is currently your input you can expand the mux with Kp and Ki and call it like:
Kp = u(5);
Ki = u(6);
This would of course depend on how big the input mux is and the position of those two values on the mux.
And all along my problem was the mux!
I wasn't aware that the u(x) was referencing the mux input x, I had thought that was a system function it was referencing. Also for a note to anyone doing the same thing, you have to change the sizes.NumInputs to agree with the size of your mux. Also, in my case, I ran into some data dependency errors with the action blocks within my subsystems. Those can be taken care of by adding in a memory block in the loop before the action subsystem is accessed.
Everything seems to be working great now, thanks again for your incredible help!

Melden Sie sich an, um zu kommentieren.

Produkte

Gefragt:

am 17 Jul. 2012

Community Treasure Hunt

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

Start Hunting!

Translated by