How to create sequence of random numbers in simulink that is non-repeating for every run and supports code generation?

27 visualizzazioni (ultimi 30 giorni)
I am trying to create true random numbers in Simulink. I am using the 'rand' and 'normrnd' functions in a MATLAB function blocks.
However, everytime I run my simulation, I see the same sequence of random numbers as the output. I read somewhere to use the command 'coder.extrinsic('rand')' inside the function block. Adding 'coder.extrinsic('rand')' works well during simulation but is not supported for stand-alone code generation.
How to create sequence of random numbers in Simulink that is non-repeating for every run and supports code generation?

Risposta accettata

MathWorks Support Team
MathWorks Support Team il 24 Ott 2022
Modificato: MathWorks Support Team il 24 Ott 2022
There are three possible solutions as listed below : 
1) Using the  rng('shuffle') command before calling the 'rand' function. Use of rng('shuffle') is only available for standalone code generation in R2018b and later releases. 
2) Implement a logic so that the state of the random number generator is initialized based on the system clock each time the application is run, and so the output will contain a unique value each time. You can understand this approach more from this MATLAB Answers post:
Since the MATLAB "clock" command does not help after code generation, you may use the "time" function from the C standard library. The time function from the C standard library can be called to set the unique seed by using "coder.cinclude" and "coder.ceval" as below:
function out = Func_Name (in1, in2)
coder.cinclude('"time.h"')
sd=0;
sd=coder.ceval('time',[]);
rng(sd,'twister');
out = zeros(1,1);
out = normrnd(in1, in2);
Now using these commands, the CodeGen build is smooth and completes without any warnings. However, if you simulate the model or If you run the executable, you will notice that, it keeps returning the same output value for "Func_Name" block for each second. 
The core reason for this is that the C function "time" returns time in seconds, and so as a result we keep seeding the same value during the simulation for each second. As a result you will see that the output changes once a second. What is happening is that we are resetting the random number generator with this "constant" seed value every time before we use the "rand" command. This resets the random number generator and outputs same constant value for the second. 
The generated code may fail on the hardware. Especially, when random numbers are being generated at a high frequency. The workaround for this behaviour is to seed the random number generator once every time the code is run as a new instance.
The two possible sub-solutions are as given below :
2a) Using a "Clock" block to feed simulation time to the MATLAB function block. Based on this time, we can use a if loop to seed the random number generator only once. You can also use a global variable as a counter instead of the simulation time to seed the random number generator only once.
function out = Func_Name (in1, in2)
coder.cinclude('"time.h"')
if simTime < 0.001
sd=0;
sd=coder.ceval('time',[]);
rng(sd,'twister');
end
out = zeros(1,1);
out = normrnd(in1, in2);
2b) Using a Stateflow chart.
A more elegant way is to use a Stateflow chart. A stateflow chart would easily be able to run the "rng(seed,'twister')" command only once at the start of the run. This way you don't have to add the clock block into the model. 
3) Use an S-function.
If you have any external C-code that you have tested for errors, then you can create a S-function. S-function will need a TLC file but do support code generation. 

Più risposte (0)

Tag

Non è stata ancora inserito alcun tag.

Prodotti


Release

R2017a

Community Treasure Hunt

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

Start Hunting!

Translated by