Error overwriting array when using Simulink

1 回表示 (過去 30 日間)
Dmytro Sokol
Dmytro Sokol 2024 年 6 月 22 日
回答済み: R 2024 年 6 月 25 日
The following error I get when running the model:
An error occurred while running the simulation and the simulation was terminated
Caused by: Size mismatch for MATLAB expression 'array'. Expected = 1x100 Actual = 1x1
The model includes two functions: (1) adding and (2) deleting elements from the array in a base workspace. Fixed-step solver is set for the model, so a new elements is added (or an existing element is removed) each tick.
Then, both functions use a class with the following methods: declare the array, add/delete an element, refresh the array. In the functions I use a persistent variable for the class.
The functions and class work properly via Command Window. But that error occurs if the functions call from the Simulink model. It happens when the array refresh method is used.
Instead of using the array refresh method, I tried to use a global variable. It also works to me via the Command Window, however other errors happen to Simulink:
Global declaration not resolved to a Data Store Memory block registered via the Ports and Data Manager.

回答 (2 件)

aditi bagora
aditi bagora 2024 年 6 月 25 日
Hey Dmytro,
I understand you have a Simulink model with functions that add or delete elements from an array. While these functions work fine when executed from the command window, you are encountering errors when running the model.
In case you are using 'persistent' variable, ensure that the variable is initialized with a constant and the function flow does not interrupt the control flow. Please refer to the following MathWorks documentation for the requirements on initializing 'persistent' variables:
If you're using a 'global' variable, you should store global data using Data Store Memory blocks. To resolve the error, follow these steps to define global data with a Data Store Memory block:
  1. Declare a global variable in your MATLAB Function block.
  2. In the MATLAB Function block, add a variable in the Symbols pane with the same name as the global variable.
  3. Set the Scope property of the variable to Data Store Memory.
  4. In the model, create a Data Store Memory block.
  5. Assign the Data store name parameter to the same name as the global variable.
  6. In the Data Store Memory, set the Initial value, Data type, and Signal type parameters. You can also refer to the following MathWorks documentation link for further information: https://www.mathworks.com/help/simulink/ug/using-global-data-with-the-matlab-function-block.html
I hope this helps in resolving the errors.

R
R 2024 年 6 月 25 日
It is challenging to diagnose the specific error without access to the model, but I created a sample model using a class in the workspace with methods for addition and deletion operations, utilizing a persistent variable, and it worked successfully.
To address the error, ensure that the array's size is correctly managed within the class definition when elements are added or deleted. You can implement an additional method to specifically check for size management errors.
Refer to such a sample class definition below:
classdef ArrayManager
properties
array
maxSize
currentSize
end
methods
function obj = ArrayManager(initialSize)
if nargin < 1
initialSize = 100; % Default size
end
obj.array = zeros(1, initialSize); % Initialize array with the expected size
obj.maxSize = initialSize;
obj.currentSize = 15; % Initialize with 15 elements
obj.array(1:15) = randi([1, 50], 1, 15); % Pre-initialize first 15 values with random numbers from 1 to 50
disp('Array initialized with first 15 values:');
disp(obj.array(1:15));
end
function obj = addElement(obj, element)
% Add element to the array
if obj.currentSize < obj.maxSize
obj.currentSize = obj.currentSize + 1;
obj.array(obj.currentSize) = element;
fprintf('Added element %d at index %d. Current array:\n', int32(element), int32(obj.currentSize));
disp(obj.array(1:obj.currentSize));
else
error('Array is already at maximum size of %d elements.', obj.maxSize);
end
end
function obj = deleteElement(obj, index)
% Delete element from the array
fprintf('Attempting to delete element at index: %d\n', int32(index));
fprintf('Current array size: %d\n', int32(obj.currentSize));
if obj.currentSize == 0
error('Cannot delete from an empty array.');
end
if index > 0 && index <= obj.currentSize
obj.array(index) = 0; % Mark the slot as unused
% Optionally, shift elements to the left to keep array compact
if index < obj.currentSize
obj.array(index:obj.currentSize-1) = obj.array(index+1:obj.currentSize);
end
obj.array(obj.currentSize) = 0;
obj.currentSize = obj.currentSize - 1;
fprintf('Deleted element at index %d. Current array:\n', int32(index));
disp(obj.array(1:obj.currentSize));
else
error('Index out of bounds. Index: %d, Current Size: %d', int32(index), int32(obj.currentSize));
end
end
function obj = refreshArray(obj)
% Ensure array size is correct
actualSize = nnz(obj.array); % Number of non-zero elements
if actualSize > obj.maxSize
error('Size mismatch for array. Expected = 1x%d Actual = 1x%d', int32(obj.maxSize), int32(actualSize));
end
end
end
end
Now, to test this, I used two MATLAB function blocks-
1) AddElement Function: It adds a new element to the end of the array managed by the ArrayManager class, increasing the current size of the array. It ensures that the array does not exceed its maximum size and provides feedback on the added element and the updated array state.
function y = AddElement(element)
persistent arrayManager
if isempty(arrayManager)
arrayManager = ArrayManager();
end
arrayManager = arrayManager.addElement(element);
arrayManager = arrayManager.refreshArray();
y = element; % Output the added element for visualization (optional)
end
2) DeleteElement Function block: It attempts to delete an element at a specified index in the array managed by the ArrayManager class, shifting subsequent elements left to maintain array compactness. It also updates the current size of the array and provides error handling if the index is out of bounds or the array is empty.
function y = AddElement(element)
persistent arrayManager
if isempty(arrayManager)
arrayManager = ArrayManager();
end
arrayManager = arrayManager.addElement(element);
arrayManager = arrayManager.refreshArray();
y = element; % Output the added element for visualization (optional)
end
Here's a screenshot of the sample model:
I used a MonitorArray function block to output the current state of the array managed by the ArrayManager class. It allows one to observe the contents of the array at different points during the simulation. This was useful for me in debugging and verifying that the array operations (addition and deletion) are being performed correctly.
I have pre-initialized the array with 15 values just to test the blocks separately.
Here's the diagnostic that verifies the operations:
Array initialized with first 15 values: Columns 1 through 9 41 46 7 46 32 5 14 28 48 Columns 10 through 15 49 8 49 48 25 41 Attempting to delete element at index: 10 Current array size: 15 Deleted element at index 10. Current array: Columns 1 through 9 41 46 7 46 32 5 14 28 48 Columns 10 through 14 8 49 48 25 41
I have attached the model as 'sampleAddDelete_model.slx' and 'ArrayManager.m' classdef for your reference.

カテゴリ

Help Center および File ExchangeNaming Conventions についてさらに検索

製品


リリース

R2019b

Community Treasure Hunt

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

Start Hunting!

Translated by