The Drawback
Right here is an easy mannequin just like the one I’ve been utilizing not too long ago in a number of posts.
When simulating the mannequin, we get the identical error as reported in MATLAB Solutions:
in = Simulink.SimulationInput(mdl);
in = in.setModelParameter(‘Stoptime’,‘500’);
in = in.setModelParameter(‘CaptureErrors’,‘on’);
This error could be triggered by a number of causes. Earlier than diving into the explanations, I want to spotlight the instruments which are the more than likely that can assist you diagnose the sort of difficulty.
Debugging Instruments
Solver Profiler
Within the Discover Gallery, launch the States Explorer.
It will help you shortly scan all of the states within the mannequin and determine which states are diverging:
Spotlight Supply
As soon as enabled, use the arrow keys to spotlight the upstream blocks feeding the integrator and take a look at understanding the logic making the equations unstable.
Simulink Debugger
Choose the sign coming into the problematic block and add a breakpoint. You may have the choice to interrupt on Inf or NaN, however I like to recommend breaking earlier to raised observe what occurs earlier than the error.
Click on Run and when the breakpoint is hit, it is possible for you to to step block by block to attempt figuring out the issue with the equations in your mannequin.
Let’s now have a look at the most typical conditions resulting in this error.
Cause 1: Unstable System
The commonest cause for this error is that equations within the mannequin are unstable. This normally occurs if the algorithm has been applied incorrectly, or if you’re simulating a system that’s actually unstable.
It may be helpful to plot the state talked about within the error message to see that it diverges towards infinity:
plot(out.xout.get(‘dx’).Values)
On this simulation, the dimensions of the mannequin makes it simple to determine the issue. Right here is an animation the place I enabled port worth show for all blocks and I’m slowly stepping the mannequin ahead so we will see the evolution of every sign. Discover how the values are rising at every time step:
The implementation mistake right here is that indicators specified within the Sum block lead to a optimistic suggestions loop. To resolve the issue and make this simulation behave because the mass-spring-damper it’s making an attempt to mannequin, we have to make the indicators of the suggestions alerts coming into the Sum block damaging.
in = Simulink.SimulationInput(mdl);
in = in.setBlockParameter(‘suspension/Sum’,‘Inputs’,‘+–‘);
plot(out.xout.get(‘dx’).Values)
Cause 2: Step measurement is simply too giant
As described within the error message, one attainable cause for this error is the solver taking too giant steps. This usually occurs when utilizing fixed-step solver, which is critical to generate code and deploy to real-time techniques.
Here’s a barely completely different model of the mannequin.
mdl = “suspensionFixedStep”;
I fastened the indicators of the Sum block to make the equations secure, however I modified the solver to ode3 with a step measurement of 1 second.
I’ll simulate the mannequin with bigger values for ok and c, making the system dynamic quick and unimaginable to seize correctly with the step sized of 1 seconds.
in = Simulink.SimulationInput(mdl);
in = in.setModelParameter(‘CaptureErrors’,‘on’);
in = in.setVariable(‘ok’,1e5);
in = in.setVariable(‘c’,100);
There are a number of methods to investigate the system and resolve the way to take care of this error.
Evaluation 1: The Equations
Which means that the system will oscillate at a frequency of:
To seize this oscillation precisely, we want not less than a minimal variety of factors per oscillation.
Evaluation 2: Linearization
[wn, zeta, p] = damp(linsys);
Evaluation 3: Variable-Step Solver
When getting this error with a fixed-step solver, one choice is simulating the mannequin with a variable-step solver. First, this provides you an excellent reference by way of accuracy.
in = Simulink.SimulationInput(mdl);
in = in.setModelParameter(‘SolverType’,‘Variable-step’);
in = in.setModelParameter(‘StopTime’,‘0.2’);
in = in.setVariable(‘ok’,1e5);
in = in.setVariable(‘c’,100);
plot(outVarStep.xout.get(‘dx’).Values);
When you higher perceive the system dynamic, it is time to look into options.
Answer 1: Smaller step-size
Let’s attempt simulating the mannequin with completely different fixed-step measurement and see what the outcomes seem like.
ts = [0.0005 0.001 0.002 0.005 0.01];
in(1:size(ts)) = Simulink.SimulationInput(mdl);
in(i) = in(i).setModelParameter(‘FixedStep’,num2str(ts(i)));
in(i) = in(i).setModelParameter(‘StopTime’,‘0.2’);
in(i) = in(i).setVariable(‘ok’,1e5);
in(i) = in(i).setVariable(‘c’,100);
out = sim(in,‘ShowProgress’,‘off’);
Trying on the outcomes, we will see that they change into much less and fewer correct because the step measurement enhance. If simulated for a bigger cease time, the final step measurement of 0.01 would ultimately error out with the infinite by-product error.
plot(outVarStep.xout.get(‘dx’).Values,‘linewidth’,2);
plot(out(i).xout.get(‘dx’).Values)
legendLabel{i} = [‘Ts=” num2str(ts(i))]; %#okay<SAGROW>
legend([ ‘Variable-Step’ legendLabel]);
Answer 2: Use a distinct solver
The solver getting used can even affect the accuracy of the outcomes. The upper the order, the extra computationally costly, but additionally the extra correct a solver is.
solvers = {‘ode1’,‘ode3’,‘ode5’,‘ode1be’};
in(1:size(solvers)) = Simulink.SimulationInput(mdl);
for i = 1:size(solvers)
in(i) = in(i).setModelParameter(‘FixedStep’,‘0.005’);
in(i) = in(i).setModelParameter(‘StopTime’,‘0.5’);
in(i) = in(i).setModelParameter(‘Solver’,solvers{i});
in(i) = in(i).setVariable(‘ok’,1e5);
in(i) = in(i).setVariable(‘c’,100);
out = sim(in,‘ShowProgress’,‘off’);
plot(outVarStep.xout.get(‘dx’).Values,‘linewidth’,2);
for i = 1:size(solvers)
plot(out(i).xout.get(‘dx’).Values)
axis([0 0.2 -2.5e-3 2.5e-3])
legend([‘ Variable-Step’ solvers]);
Answer 3: Modify the system dynamics
In some circumstances, real-time constraints could make it unimaginable to make use of a bigger step-size or a extra correct solver. In such case, the answer is more than likely to attempt simplifying the system equations or to melt the dynamics.
Division by Zero
in = Simulink.SimulationInput(mdl);
in = in.setModelParameter(‘CaptureErrors’,‘on’);
To diagnose this, I like to recommend utilizing the Simulink Debugger. Setting a breakpoint on Inf or NaN will cease the simulation on the first block the place the Inf is generated.
On this case, the answer is to change the equations to keep away from feeding Inf to Integrator blocks.
Now it is your flip
Have you ever run into issues with infinite by-product error? Tell us within the feedback beneath.