[Simulink] Rate limiter dynamic with a variable-step solver
조회 수: 21 (최근 30일)
이전 댓글 표시
Hi everybody,
i need to use a "rate limiter dynamic" block in my Simulink model. But, the latter runs only with a fixed-step solver. Anybody have an idea to code an alternative solution to do this operation ? A precision : i just want to fixe a variable slew rate limitation ; the falling rate limitation is always equal to -inf.
Thanks in advance :)
댓글 수: 0
답변 (3개)
Ryan G
2013년 9월 13일
You could put a rate transition on the input signal to the block. This would make the input signal fixed sample time and resolve the error. Otherwise, you would have to derive this manually. The challenge with variable time steps is that you need to somehow determine how big the time step is.
If you look at the error it points you to the Ts block under the mask. This outputs the signals sample time (fixed). If you did this for variable step you could setup like this using clock and memory blocks with a summing junction:
(clock) -> (memory) -> (-) (clock) -> (+) = time step
This time step should give you similar results. I can't guarantee the accuracy versus the shipping block.
댓글 수: 0
Steve Theberge
2019년 3월 29일
This is the solution I came up with, it's not elegant so I would like to know if someone came up with something better. I created a subsystem with the following blocks inside:
The Rate Limiter block runs in variable step solvers but doesn't have input ports for rate limits, these are set in the Parameters inside the block. It so happens that you can change these parameters while the simulation is running, either manually by double clicking the block or by using the set_param command. Here I am using an embedded MATLAB function (the block named "Set_param for RateLimit") to do this. The code inside this block is as follows:
function RtLim(up,dn)
eml.extrinsic('evalin');
eml.extrinsic('set_param');
eml.extrinsic('num2str');
persistent up_z;
persistent dn_z;
if (isempty(up_z))
up_z = 0.99*up;
dn_z = 0.99*dn;
end
if up_z ~= up || dn_z ~= dn
evalin('caller', 'blocknameWS = gcb;'); %get full name of current block
blockname = evalin('caller', 'blocknameWS(1:end-35);');%removes "Set_param for Ratelimit/ SFunction " from end of string
blockname = [blockname 'Rate Limiter']; %concatenate "Rate Limiter" to end of string
set_param(blockname, 'risingSlewLimit', num2str(up));
set_param(blockname, 'fallingSlewLimit', num2str(dn));
end
up_z = up;
dn_z = dn;
end
This code builds the full block name of the rate limiter block and stores the string in the variable "blockname". Then it uses that in the set_param command. That way the subsystem can be copied and pasted in other areas of the model and renamed and it will work without having to change anything inside (Note: careful if you rename the rate limiter block since the code depends on that name and also if you rename the Embedded MATLAB function since the code depends on that name being a certain length. Also note that here I am checking if the rate settings have changed before calling the evalin and set_param commands (in my case they only change occasionally so the model executes faster if I don't constantly execute the evalin and set_param commands for nothing).
댓글 수: 0
참고 항목
카테고리
Help Center 및 File Exchange에서 Programmatic Model Editing에 대해 자세히 알아보기
제품
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!