Search code examples
matlabsimulink

How to access variables in the properties block of a Matlab System Object?


I am working on a simple System Object in Matlab/Simulink.

It looks like this :

classdef realtime_header_detectorSO < matlab.System & matlab.system.mixin.Propagates
    % correlateHeader
    %
    % This template includes the minimum set of functions required
    % to define a System object with discrete state.

    properties
       Header
       %nrOfBitsInPreviousStep=0;
       s=100;
       d=zeros(1,s);



    end

    properties (DiscreteState)

    end

    properties (Access = private)
              max_nr_of_packets=20;
      max_packet_length_in_bytes=300;
      current_packet=1;
        % Pre-computed constants.
     %   h = commsrc.pn('GenPoly', [9 5 0],'NumBitsOut', 8,'InitialStates',ones(1,9));
  %   data=logical(zeros(max_nr_of_packets,max_packet_length_in_bytes*8));
    end

    methods (Access = protected)
        function setupImpl(obj,u)
            % Implement tasks that need to be performed only once, 
            % such as pre-computed constants.

        end

        function [maxCorr]= stepImpl(obj,u)
            eml.extrinsic('num2str');
             coder.extrinsic('sprintf');
            % Implement algorithm. Calculate y as a function of
            % input u and discrete states.
            %y = size(u,1);

                symbols=sign(u);
                c=abs(conv(flipud(obj.Header),[symbols; symbols]));

                maxCorr=max(c);    
              %  maxCorr
                if(maxCorr==36)

                    idx36=find(c(1:size(symbols,1))==36);
                    disp('header(s) detected at the following location(s) in bytes:');
                    disp(sprintf('%15.4f \n',idx36/8));
                    nrOfSymbols=size(symbols,1);
                    disp(['out of nr. of total symbols: ' num2str(nrOfSymbols)]);
                    disp('------');
                %    maxCorr
                end
            % y=obj.pBufferIdx;
        end

        function resetImpl(obj)
            % Initialize discrete-state properties.
        end

        function varargout = isOutputFixedSizeImpl(~)
             varargout = {true};
        end

        function varargout = getOutputSizeImpl(obj)
           varargout = {[1 1]};
        end
    end

end

However when I compile/run it I get the following error:

The System object name 'realtime_header_detectorSO' specified in MATLAB System block 'freqScanningRT/Sync and
Find Header/detect header' is invalid.

Caused by:
    Undefined function or variable 's'.

However (!) the following code compiles and runs just fine :

classdef realtime_header_detectorSO < matlab.System & matlab.system.mixin.Propagates
    % correlateHeader
    %
    % This template includes the minimum set of functions required
    % to define a System object with discrete state.

    properties
       Header
       %nrOfBitsInPreviousStep=0;
       s=100;
  %     d=zeros(1,s);



    end

    properties (DiscreteState)

    end

    properties (Access = private)
              max_nr_of_packets=20;
      max_packet_length_in_bytes=300;
      current_packet=1;
        % Pre-computed constants.
     %   h = commsrc.pn('GenPoly', [9 5 0],'NumBitsOut', 8,'InitialStates',ones(1,9));
  %   data=logical(zeros(max_nr_of_packets,max_packet_length_in_bytes*8));
    end

    methods (Access = protected)
        function setupImpl(obj,u)
            % Implement tasks that need to be performed only once, 
            % such as pre-computed constants.

        end

        function [maxCorr]= stepImpl(obj,u)
            eml.extrinsic('num2str');
             coder.extrinsic('sprintf');
            % Implement algorithm. Calculate y as a function of
            % input u and discrete states.
            %y = size(u,1);
                disp(obj.s);
                symbols=sign(u);
                c=abs(conv(flipud(obj.Header),[symbols; symbols]));

                maxCorr=max(c);    
              %  maxCorr
                if(maxCorr==36)

                    idx36=find(c(1:size(symbols,1))==36);
                    disp('header(s) detected at the following location(s) in bytes:');
                    disp(sprintf('%15.4f \n',idx36/8));
                    nrOfSymbols=size(symbols,1);
                    disp(['out of nr. of total symbols: ' num2str(nrOfSymbols)]);
                    disp('------');
                %    maxCorr
                end
            % y=obj.pBufferIdx;
        end

        function resetImpl(obj)
            % Initialize discrete-state properties.
        end

        function varargout = isOutputFixedSizeImpl(~)
             varargout = {true};
        end

        function varargout = getOutputSizeImpl(obj)
           varargout = {[1 1]};
        end
    end

end

So I can access s in the stepImpl(obj,u) as obj.s but I cannot access s inside the properties block, where it is defined !

Now this is confusing.

Is there way to access s inside the properties block ?

The problem is that I have to use the properties block because if I try this :

 function setupImpl(obj,u)
        % Implement tasks that need to be performed only once, 
        % such as pre-computed constants.
        d=zeros(1,obj.s);

  end

then I get :

Error due to multiple causes.

Caused by:
    Problem creating simulation target MEX-file for model 'freqScanningRT'.
    Simulink detected an  error
     'Computed maximum size is not bounded.
    Static memory allocation requires all sizes to be bounded.
    The computed size is [1 x :?].'.

     The error occurred for MATLAB System block 'freqScanningRT/Sync and Find Header/detect header'. See line
     34, column 15 in file
     'path/realtime_header_detectorSO.m'.
     The error was detected during code generation phase.
     Start code generation report.

     To prevent this error, use one of the following:
     * Modify the System object to avoid code that does not support code generation.
     * Change 'Simulate using' parameter to 'Interpreted Execution'.

Any idea how to refer to variables in the properties blocks ?

There must be a way to do this.


Solution

  • You should be able to use

    properties
           s = 100;
           d = zeros(1,100);
    end
    

    right? If you already have the 100 as a default for s, you should also be able to provide this as part of the default for d.

    I'm guessing that you're trying to avoid doing that because you feel uncomfortable repeating the "100". But I'd also guess that really, "100" is some sort of magic number that your system depends on; so really, you should try to pull it out as a constant in any case, whether it's repeated or not.

    So in that case, you might improve things with

    properties (Constant)
        MYCONSTANT = 100;
    end
    
    properties
           % Reference Constant class properties with the class name
           s = realtime_header_detectorSO.MYCONSTANT;
           d = zeros(1, realtime_header_detectorSO.MYCONSTANT);
    end
    

    You're not going to be able to do what you're originally trying to do - it's not possible to reference the name of one property within the property definition block when defining another property (even though you can perfectly well reference it within a method). I guess I understand why you find that confusing - but to clear up your confusion, note that you have no guarantee over the order in which MATLAB instantiates default values for properties. If it tried to create d before it had created s, it would obviously fail.