保持恒定信号
Hold constant signal
我在Simulink中有一个动态系统的模型(我不能改变编程框架)。它可以描述为周期性振荡的振荡器。我正在尝试控制它的运动,特别是要使其最大化(用于产生能量)。
使用锁存控制(一种流行的控制策略),其思想是'latch',即当设备的速度为 0 达到预定时间时锁定到位,然后释放它直到其速度达到又是 0。
因此,我需要在 Simulink 中做的是在速度信号达到(或接近)0
后输出一个信号 1
,并在一段时间内保持恒定(在1
),然后释放它(信号变为0
),并在速度再次达到0
时重复该过程。
我找到了一篇关于在 Simulink 中保持信号恒定的好博客:
http://blogs.mathworks.com/simulink/2014/08/06/how-do-you-hold-the-value-of-a-signal/
然而,在我的例子中,我有两个条件来确定信号:速度的大小和时间段内的时间。现在,问题是一旦周期结束,设备被释放(信号 = 0
),速度仍然很小,这可能导致 1
的错误信号,如果使用了 if 循环。
我认为使用 S-Function 可能是最好的解决方案,但我将不得不使用固定的时间步长。是否有针对此问题的任何 Simulink 原生解决方案?
最后我临时用了一个Matlab的函数,很有效。我的灵感来自 https://uk.mathworks.com/matlabcentral/answers/11323-hold-true-value-for-finite-length-of-time
u
为速度信号。
function y = fcn(u,nlatch)
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% This function is used to determine the latching signal.
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% Using persistent memory:
persistent tick started sign;
% Initialize variables:
if isempty(tick)
tick = 0;
started = 0;
sign = (u>0);
end
U=0; % no latching
s=(u>0);
if s~=sign
started = 1;
end
if started
if tick<nlatch
tick=tick+1;
U = 1;
else
tick = 0;
started = 0;
sign = s;
end
end
y = U;
end
然而,正如我提到的,我必须使用固定步长求解器,这对我来说没什么大不了的,但它会给其他用户带来问题。
如果谁有更"Simulink-native"的解决办法,请告诉我!
编辑
我现在修改了该功能:现在,当速度信号的符号发生变化时应用锁存,而不是像之前那样查看较小的幅度(abs(u)<0.005
),这太具体了。
我的一个同事也找到了一个 Simulink-native 解决方案:
但是,当采用相同的时间步长时,Matlab 函数速度更快(计算强度更低)。也许计算密集度最低的解决方案是 C S 函数。
我在Simulink中有一个动态系统的模型(我不能改变编程框架)。它可以描述为周期性振荡的振荡器。我正在尝试控制它的运动,特别是要使其最大化(用于产生能量)。
使用锁存控制(一种流行的控制策略),其思想是'latch',即当设备的速度为 0 达到预定时间时锁定到位,然后释放它直到其速度达到又是 0。
因此,我需要在 Simulink 中做的是在速度信号达到(或接近)0
后输出一个信号 1
,并在一段时间内保持恒定(在1
),然后释放它(信号变为0
),并在速度再次达到0
时重复该过程。
我找到了一篇关于在 Simulink 中保持信号恒定的好博客: http://blogs.mathworks.com/simulink/2014/08/06/how-do-you-hold-the-value-of-a-signal/
然而,在我的例子中,我有两个条件来确定信号:速度的大小和时间段内的时间。现在,问题是一旦周期结束,设备被释放(信号 = 0
),速度仍然很小,这可能导致 1
的错误信号,如果使用了 if 循环。
我认为使用 S-Function 可能是最好的解决方案,但我将不得不使用固定的时间步长。是否有针对此问题的任何 Simulink 原生解决方案?
最后我临时用了一个Matlab的函数,很有效。我的灵感来自 https://uk.mathworks.com/matlabcentral/answers/11323-hold-true-value-for-finite-length-of-time
u
为速度信号。
function y = fcn(u,nlatch)
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% This function is used to determine the latching signal.
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% Using persistent memory:
persistent tick started sign;
% Initialize variables:
if isempty(tick)
tick = 0;
started = 0;
sign = (u>0);
end
U=0; % no latching
s=(u>0);
if s~=sign
started = 1;
end
if started
if tick<nlatch
tick=tick+1;
U = 1;
else
tick = 0;
started = 0;
sign = s;
end
end
y = U;
end
然而,正如我提到的,我必须使用固定步长求解器,这对我来说没什么大不了的,但它会给其他用户带来问题。
如果谁有更"Simulink-native"的解决办法,请告诉我!
编辑
我现在修改了该功能:现在,当速度信号的符号发生变化时应用锁存,而不是像之前那样查看较小的幅度(abs(u)<0.005
),这太具体了。
我的一个同事也找到了一个 Simulink-native 解决方案: