Hi, I am new to Matlab. I have a merge block that outputs either a 1 or 0. What I want to do is; If the input to the function block is 0, i want the output to be 0 and not be able to change back to 1. if the input is 1 i want the output to be a 1 but be able to change to a 0. is it possible to implement this? thank you in advance!

 채택된 답변

Honglei Chen
Honglei Chen 2017년 5월 24일

1 개 추천

I think you can use persistent variable to set a flag in the function block. If the input is ever 0, then you just ignore the future input. Something like this
function y = fcn(u)
persistent flag
if isempty(flag)
flag = true;
end
if flag
y = u;
if u == 0
flag = false;
end
else
y = 0;
end
end
HTH

댓글 수: 4

function y = fcn(u)
persistent lastval
if isempty(lasval); lastval = cast(1, class(u)); end
y = cast(u & lastval, class(u));
lastval = y;
which can be simplified a little if the datatype of u can be restricted. I did not wish to guess whether this was all to happen as double or as uint8.
John Whelan
John Whelan 2017년 5월 24일
That worked brilliant thank you! Just one more thing, is there a way you could add to that code to run after 0.5s of the simulation?? At the moment the system settling period is causing the value to change to a 0, however i dont want the settling period to affect the value. Thanks in advance!
Honglei Chen
Honglei Chen 2017년 5월 24일
편집: Honglei Chen 2017년 5월 24일
You can try to use a switch block at the input, as shown here
so that one of the input is to your real input and the other one to a constant 1. For the condition, you can use a clock
and compare its output with the 0.5 threshold.
HTH
Walter Roberson
Walter Roberson 2017년 5월 24일
편집: Walter Roberson 2017년 5월 24일
Add a Clock or Digital Clock block and run the input to the second port. Then,
function y = fcn(u, t)
persistent lastval
if isempty(lasval); lastval = cast(1, class(u)); end
if t <= 0.5
y = u;
else
y = cast(u & lastval, class(u));
lastval = y;
end

댓글을 달려면 로그인하십시오.

추가 답변 (1개)

Les Beckham
Les Beckham 2017년 5월 25일

1 개 추천

Note that you can also do this with simple Simulink blocks (and no Matlab function block). If you don't have to protect against the input being zero during the first 0.5 seconds, it only takes two blocks. With the protection, it takes five. Here is an example. Be sure that you set the initial condition on the Memory block. You probably also want to make sure the decimation on the Clock block is set to 1.
<<
>>

댓글 수: 6

Walter Roberson
Walter Roberson 2017년 5월 25일
I looked at "however i dont want the settling period to affect the value" and was unsure of what was meant, but figured that the interpretation should be that during the settling period, the output should be the same as the input.
Les Beckham
Les Beckham 2017년 5월 25일
That would, of course, be a valid way of interpreting the not-quite-clear requirement. I interpreted it as 'ignore a zero input during the "settling period" so it won't latch'. The OP will have to decide what they really want.
I should mention that there are advantages to using 'basic' Simulink blocks in terms of simulation performance (among other things) and using a Matlab function block where it isn't really needed can sometimes cause unexpected issues (especially when you use persistent variables). For relatively simple models it probably doesn't matter.
John Whelan
John Whelan 2017년 5월 25일
편집: Walter Roberson 2017년 6월 5일
@Les Becham, yes you interpreted me right, sorry it wasnt well explained. So how can i add to the following function block code to implement this?
function y = fcn(u)
persistent flag
if isempty(flag)
flag = true;
end
if flag
y = u;
if u == 0
flag = false;
end
else
y = 0;
end
end
Les Beckham
Les Beckham 2017년 6월 4일
편집: Les Beckham 2017년 6월 4일
If you wish the output to be forced to 1 during the first 0.5 seconds and insist on using a Matlab function block, I would adapt Walter's last suggestion as follows:
function y = fcn(u, t)
persistent lastval
if isempty(lastval); lastval = cast(1, class(u)); end
if t <= 0.5
y = cast(1, class(u));
else
y = cast(u & lastval, class(u));
lastval = y;
end
Note that the cast(..., class(u)) construct is a good strategy to make sure that this block will robustly handle whatever type (class) of signal you connect to it as an input (e.g., double, uint8, logical). I wouldn't have thought of that. Thanks to Walter for educating me again.
I think, though, that this construct may not be needed in the 'else' section, as u and lastval should already be of the correct class (and, thus, so will the resulting y). Nevertheless, it doesn't hurt anything to keep it.
BTW: the approach I suggested using basic Simulink blocks is also robust to different input signal classes as most basic Simulink blocks are designed to be class agnostic.
Walter Roberson
Walter Roberson 2017년 6월 5일
편집: Walter Roberson 2017년 6월 5일
I think you are right that
y = cast(u & lastval, class(u));
could be abbreviated as
y = u & lastval;
unless somehow the block was being called multiple times with different signal types (or unless somehow the signal type of the input can change during execution -- just because I can't think of a way that could happen doesn't mean it isn't possible.)
But mostly I think I put in the explicit typecast to be sure that code generation would know for sure what the output type would be, instead of code generation having to deduce that it is holding the correct type because of a persistent variable assigned to in the past.
Les Beckham
Les Beckham 2017년 6월 5일
I agree completely that this is good 'defensive programming' practice.
I do like to encourage the use of built-in Simulink blocks where possible as I've found them more efficient and portable (across versions, etc.).
Of course, the original question was about a Matlab function block implementation. I just wanted to show that there was an alternative.

댓글을 달려면 로그인하십시오.

카테고리

도움말 센터File Exchange에서 General Applications에 대해 자세히 알아보기

질문:

2017년 5월 24일

댓글:

2017년 6월 5일

Community Treasure Hunt

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

Start Hunting!

Translated by