我对MATLAB比较熟悉,但是对Simulink来说是新的。在simulink中将可变大小的数组填充到固定大小
我想建立一个模型,我需要(似乎需要)使用可变大小的数组,其尺寸因时间步长而异。
考虑以下问题:
- 假设我的模拟长为10秒和我的时间步长固定为1秒。然后我可以构造我的时间数组TT = [1 2 3 4 5 6 7 8 9 10]。
- 我有一个固定大小的数组A [5 6 3]。
- 我的目标是在每个时间步骤,使得以构成阵列AA:
在时间= 0,AA = [5 6 3 0 0 0 0 0 0 0]
在时间= 1,在时间= 2时,AA = [0 5 6 3 0 0 0 0 0 0]
,AA = [0 0 5 6 3 0 0 0 0 0]
...
在时间=在时间= 8时,AA = [0 0 0 0 0 0 0 5 6]
,AA = [0 0 0 0 0 0 0 0] 0 0 0 0 0 0 0 5 6 3]
0 5]
at time = 10,AA = [0 0 0 0 0 0 0 0 0 0]
什么是最简单的方法来实现这一目标?
我试着创建一个2级MATLAB S函数,只是调整给定的例子。见下面的代码。该函数只是生成一个当前时间大小的零数组。这导致可变大小的数组。
这是我使用的2级MATLAB S函数。我只更改了msfcndemo_varsize中示例代码“expand”的最后一行,以生成零数组[0 0 0 ...]而不是[1 2 3 4 ...]。
function msfcn_varsize_expand(block)
% Level-2 MATLAB file S-Function.
% Takes a scalar input and outputs a vector of length indicated
% by its input value. The output is given by 1:n where n is the input
% value.
% For example
% f(5) = [1 2 3 4 5]
%
% The parameter defines the maximum input value allowed.
%
% Copyright 2009 The MathWorks, Inc.
setup(block);
function setup(block)
% Register number of ports and parameters
block.NumInputPorts = 1;
block.NumOutputPorts = 1;
block.NumDialogPrms = 1;
% Setup functional port properties to dynamically inherited
block.SetPreCompInpPortInfoToDynamic;
block.SetPreCompOutPortInfoToDynamic;
% Register the properties of the input port
block.InputPort(1).Complexity = 'Inherited';
block.InputPort(1).DataTypeId = -1;
block.InputPort(1).SamplingMode = 'Sample';
block.InputPort(1).DimensionsMode = 'Fixed';
block.InputPort(1).DirectFeedthrough = true;
% Register the properties of the output port
block.OutputPort(1).DimensionsMode = 'Variable';
block.OutputPort(1).SamplingMode = 'Sample';
% Register sample times
% [-1, 0] : Inherited sample time
block.SampleTimes = [-1 0];
% Register methods called during update diagram/compilation
block.RegBlockMethod('SetInputPortDimensions', @SetInputPortDims);
block.RegBlockMethod('PostPropagationSetup', @DoPostPropSetup);
% Register methods called at run-time
block.RegBlockMethod('Outputs', @Outputs);
% -------------------------------------------------------------------------
function SetInputDimsMode(block, port, dm)
% Set dimension mode
block.InputPort(port).DimensionsMode = dm;
% -------------------------------------------------------------------------
function SetInputPortDims(block, idx, di)
width = prod(di);
if width ~= 1
DAStudio.error('Simulink:blocks:multirateInvaliDimension');
end
% Set compiled dimensions
block.InputPort(idx).Dimensions = di;
block.OutputPort(idx).Dimensions =[1 block.DialogPrm(1).Data];
% -------------------------------------------------------------------------
function DoPostPropSetup(block)
% Set the type of signal size to be dependent on input values, i.e.,
% dimensions have to be updated at output
block.SignalSizesComputeType = 'FromInputValueAndSize';
% -------------------------------------------------------------------------
function Outputs(block)
% Output function:
% -update output values
% -update signal dimensions
block.OutputPort(1).CurrentDimensions = [1 block.InputPort(1).Data];
block.OutputPort(1).Data = zeros(1,block.InputPort(1).Data);
我正在使用此函数生成AA中的零,它将在A = [5 6 3]之前生成。这个想法是将这个零数组与A连接起来,这样我就可以将结果数组填充到TT的大小。但是我遇到了问题,因为垫块不接受可变大小的数组作为其输入。
一个更简单的方法我也尝试过使用pad和offset块,但问题是我无法根据模拟中的每次指定输出向量的长度。也许我错过了什么?
任何其他方法或建议或指导将是伟大的!
谢谢!
向我们展示您的代码!但是从问题描述来看,并不清楚你在哪里/为什么有一个可变大小的数组。你的'A = [5 6 3]'不是可变大小的,你的'AA'也不是。可以使用任意数量的方法在您给出的特定示例中生成您的“AA”:一个S函数,一个MATLAB函数块,... –
@PhilGoddard感谢您的好评!我已经编辑了这个问题来包含我的函数,这个函数实际上只是与Simulink中的演示函数不同的一行。你有什么具体的方法或建议? –
为什么不只是S函数输出整个'AA'矢量?使用'A'和'n'作为参数对其进行初始化,将'AA'作为一个状态存储,并且只需在每个时间步进行旋转/移位并输出结果? –