MATLAB Answers

How to use Matlab Coder to create object whose property is a container of unknown value classes

6 views (last 30 days)
Joseph Smalley
Joseph Smalley on 9 Sep 2020
Commented: Joseph Smalley on 21 Sep 2020
I am trying to convert a portion of a large program to a MEX file via MATLAB Coder. This code involves a user-defined value class, "World". The "World" class has a property, "objects" which is a cell array of other user-defined value classes ("Cube", "Sphere", "Cylinder", etc), each of which is a sub-class of the "Shape" superclass. The program should allow users to include an arbitrary number of "Shape" objects (upto an upper bound, say 10), in an arbitrary order in their "World". To this end, I created the following function which works fine in MATLAB:
function wrld = create_world(objIndxList)%#codegen
% First create instance of World class. World is a user-defined value class with "objects" property.
% The "objects" property is pre-allocated as a 1x10 cell array for compatability with codegen and hetereogeneous cell arrays.
% Each element of "objects" is initally a dummy sub-class of the user-defined "Shape" superclass
% The purpose of the create_world function is to replace some or all of the dummy sub-class objects with actual sub-class objects (e.g.,
% Cube, Sphere, Cylinder, etc)
wrld = World();
numObj = length(objIndxList); % This is the number of dummy Shape objects to replace
wrld.objCodes(1:numObj) = objIndxList; % Dummy objects have 0 as their code, whereas real objects are > 0
L = coder.const(length(wrld.objects)); % codegen requires const bounds on for loop
for i=1:L
if objIndxList(i) == 1
wrld.objects{i} = Cube();
elseif objIndxList(i) == 2
wrld.objects{i} = Sphere();
elseif objIndxList(i) == 3
wrld.objects{i} = Cylinder();
else
error('Incorrect object code')
end
if i==numObj % break from for loop once non-null objects are exhausted
break
end
end
end
For example, the output called from MATLAB with [1,2,3] as the input looks like the following:
wrld = create_world([1 2 3])
wrld =
World with properties:
objects: {1×10 cell}
objCodes: [1 2 3 0 0 0 0 0 0 0]
where objects{1:3} are 1x1 Cube, 1x1 Sphere, and 1x1 Cylinder, respectively, and objects{4:10} are 1x1 ShapeDummy.
However, using MATLAB Coder, I continuously get "Type name mismatch: ShapeDummy~=Cube", "Type name mismatch: ShapeDummy~=Sphere", "Type name mismatch: ShapeDummy~=Cylinder" errors. I understand that with C++, the type is static. So when I pre-allocate each cell of the "objects" cell array to ShapeDummy, a type mismatch is registered. I am wondering if there is a workaround of any sort for this type of problem, as it seems fairly generic.
Reading the following link: https://www.mathworks.com/help/simulink/ug/homogeneous-vs-heterogeneous-cell-arrays.html, it appears I am obeying all rules to create a heterogeneous cell array, namely fixed size, indexing into it with a constant upper bound.
Does anyone know if I am missing something or there is a workaround here?
  2 Comments
Joseph Smalley
Joseph Smalley on 21 Sep 2020
Thanks for your response, Alexander. After reading about virtual functions in C++, it indeed appears that I must create "Abstract" classes explicitly in C++ via virtual methods that would exhibit the same behavior as my abstract Shape class created in MATLAB. This way the items of the World class could be determined at runtime rather than compile-time.
I wonder why MATLAB Coder cannot support this type of conversion?

Sign in to comment.

Answers (0)

Community Treasure Hunt

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

Start Hunting!