gusucode.com > vnt工具箱matlab源码程序 > vnt/vnt/+xcp/MeasurementList.m

    classdef MeasurementList < handle
% MeasurementList Class that implements an XCP DAQ or STIM measurement list.

% Authors: JDP
% Copyright 2012 The MathWorks, Inc.

properties
    % Number - The absolute/relative ODT number for this ODT.
    Number
    % ODTObject - An array of ODT objects for the ODTs that make up this list.
    ODTObject
    % Resource - Defines whether this is a DAQ or STIM list.
    Resource
    % EventInfo - A structure of event information for this list's event.
    EventInfo
    % MeasurementInfo - An array of structures of measurement information 
    %   for all measurements in this list.
    MeasurementInfo
    % A2LFileObject - An xcp.A2L file object.
    A2LFileObject
    % ListMode - The XCP code for this list mode (ex. defines DAQ or STIM).
    ListMode
    % STIMPeriod - The rate for STIM message output for a STIM list.
    STIMPeriod
    % STIMCounter - A counter for STIM message output.
    STIMCounter
end

properties (Dependent)
    % MeasurementNames - Quick reference to the names of all measurements
    %   used by the list as a cell array of strings.
    MeasurementNames
    % NumberOfMeasurements - Quick reference to the number of measurements
    %   used by the list.
    NumberOfMeasurements
    % NumberOfODTs - Quick reference to the number of ODTs in this list.
    NumberOfODTs
end

methods
        
    function obj = MeasurementList(a2lFileObject, resource, eventInfo, measurementInfo)
    % MeasurementList Object constructor.
    %
    %   resource - String which defines whether this a 'DAQ' or 'STIM' list.
    %   eventInfo - A structure of event information for the event to which
    %       this measurement list is configured.
    %   measurementInfo - An array of structures with information about the
    %       measurements configured for this list.
        
        % Set basic properties from the input.
        obj.A2LFileObject = a2lFileObject;
        obj.Resource = resource;
        obj.EventInfo = eventInfo;
        obj.MeasurementInfo = measurementInfo;

        % Construct the list mode value for this list.
        switch obj.Resource
            case 'DAQ'
                % PID on, Timestamp off, Direction DAQ, Alternating disabled.
                obj.ListMode = bin2dec('00000000');
            case 'STIM'
                % PID on, Timestamp off, Direction STIM, Alternating disabled.
                obj.ListMode = bin2dec('00000010');
        end
            
        % Create the first ODT for this list.
        obj.ODTObject = xcp.ODT(obj.A2LFileObject);
        
        % Add the measurements to ODTs.
        for ii = 1:numel(obj.MeasurementInfo)
            % Initialize a tracking variable for placement success.
            measurementPlaced = false;
            % Try to place the measurement in each ODT until all are attempted.
            for jj = 1:numel(obj.ODTObject)
                % Add the measurement.
                measurementPlaced = obj.ODTObject(jj).addMeasurement(obj.MeasurementInfo(ii));
                % If the measurement was placed, then move on.
                if measurementPlaced
                    break;
                end
            end
            
            % If the measurement did not fit into any existing ODT, there is
            % more work to do.
            if ~measurementPlaced
                % Create a new ODT.
                obj.ODTObject = [obj.ODTObject xcp.ODT(obj.A2LFileObject)];
                % Place the measurement in the new ODT.
                obj.ODTObject(end).addMeasurement(obj.MeasurementInfo(ii));
            end
        end
        
        % For STIM lists, set the additional property values.
        if strcmpi(obj.Resource, 'STIM')
            % Set the event period in seconds as the STIM period.
            obj.STIMPeriod = obj.EventInfo.ChannelTimeCycleInSeconds;
            % Set the STIM counter to zero so that on the first execution 
            % of the STIM list task the messages will transmit.
            obj.STIMCounter = 0;
        end
    end
    
    function setODTNumbers(obj, firstNumber)
    % setODTNumbers Sets ODT numbers as absolute/relative values.
    %
    %   firstNumber - The number to use for the first ODT in the list when
    %       absolute numbering is used.
    %
    %   We need to know the ODT number for each ODT in order to decode the ODT
    %   messages when they are received for DAQ or sent for STIM. This
    %   method is used to set those values regardless of whether absolute
    %   or relative numbering is used.
    
        % If relative numbering is used, then force the first number to be
        % zero so the numbering starts fresh regardless of the input.
        if ~strcmpi(obj.A2LFileObject.DAQInfo.IdentificationFieldType, ...
                xcp.Utility.IDENTIFICATION_FIELD_TYPE_ABSOLUTE);
            firstNumber = 0;
        end
        
        % Index through the ODTs and set the numbers.
        for ii = 1:obj.NumberOfODTs
            % Using the first number as a base and given we loop starting 
            % at an index value of 1, we need to also subtract 1 so that the 
            % math works out properly for zero indexing on the ODT number.
            obj.ODTObject(ii).Number = firstNumber + ii - 1;
        end
    end

    function value = getODTObject(obj, number)
    % getODTObject Finds and returns a handle to a specific ODT by number.
    %
    %   number - The ODT number for which to search.
    %
    %   value - xcp.ODT object handle matching the ODT/PID number.
    %
    %   This method searches all the ODT objects in this list to find a
    %   match to the provided ODT number. If no match is found, the
    %   method returns empty. The number may refer to an absolute or
    %   relative number, but the methods works the same either way.
        
        % Use logical indexing to identify the requested ODT. This method
        % will automatically return empty if an ODT is not found.
        value = obj.ODTObject(number == [obj.ODTObject.Number]);
    end
    
    function configureSTIMMessageObjects(obj)
    % configureSTIMMessageObjects Configures STIM message objects for transmit.
    %
    %   This methods triggers configuration of the messages for STIM to be
    %   sent by this measurement list.
    
        % If this is a DAQ list, just return.
        if strcmpi(obj.Resource, 'DAQ')
            return;
        end
    
        % Configure a STIM message for output for each ODT.
        for ii = 1:obj.NumberOfODTs
            % Build the STIM message object.
            obj.ODTObject(ii).STIMMessageObject = can.Message( ...
                obj.A2LFileObject.TransportLayerCANInfo.CANIDMaster, ...
                obj.A2LFileObject.TransportLayerCANInfo.CANIDMasterIsExtended, ...
                8);
            
            % Set the ODT number in the message data.
            obj.ODTObject(ii).STIMMessageObject.Data(1) = obj.ODTObject(ii).Number;
            
            % Set the list number in the message data if necessary based on
            % the identification field type.
            switch obj.A2LFileObject.DAQInfo.IdentificationFieldType
                case xcp.Utility.IDENTIFICATION_FIELD_TYPE_RELATIVE_BYTE
                    obj.ODTObject(ii).STIMMessageObject.Data(2) = obj.Number;
                    
                case xcp.Utility.IDENTIFICATION_FIELD_TYPE_RELATIVE_WORD
                    obj.ODTObject(ii).STIMMessageObject.Data(2:3) = ...
                        xcp.Utility.packParameter( ...
                            obj.A2LFileObject.ProtocolLayerInfo.ByteOrder, ..., ...
                            xcp.Utility.BYTES_IN_WORD, ...
                            obj.Number);
                        
                case xcp.Utility.IDENTIFICATION_FIELD_TYPE_RELATIVE_WORD_ALIGNED
                    obj.ODTObject(ii).STIMMessageObject.Data(3:4) = ...
                        xcp.Utility.packParameter( ...
                            obj.A2LFileObject.ProtocolLayerInfo.ByteOrder, ..., ...
                            xcp.Utility.BYTES_IN_WORD, ...
                            obj.Number);
            end            
        end
    end
    
    function result = writeSTIMData(obj, measurement, value)
    % writeSTIMData Writes STIM data into the ODT STIM messages.
    %
    %   measurement - The name of the measurement to update.
    %   value - The data value to pack into the STIM message.
    %
    %   result - Boolean value indicating success or failed write.
    %
    %   This method write the provided data value into the ODT STIM message
    %   for the given measurement. The new data will then be sent via the
    %   transport layer when appropriate according to the list
    %   configuration. The method returns true if the value was written
    %   to an ODT STIM message, otherwise false.
        
        % If this is a DAQ list, just return.
        if strcmpi(obj.Resource, 'DAQ')
            result = false;
            return;
        end
    
        % Check that the specified measurement is configured in this list.
        if ~any(strcmp(measurement, obj.MeasurementNames))
            % If not found, then return as a failed action.
            result = false;
            return;
        end
        
        % Pack the data value.
        for ii = 1:obj.NumberOfODTs
            % Try to write the value to each ODT.
            result = obj.ODTObject(ii).writeSTIMData(measurement, value);
            
            % Check the result. If the write worked, then return.
            if result
                return;
            end
        end
        
        % If we get this far, the measurement could not be written to this
        % ODT, so return false;
        result = false;
    end
    
end

methods % Custom get/set methods for properties.
        
    function value = get.MeasurementNames(obj)
        value = {obj.MeasurementInfo.Name}';
    end
    
    function value = get.NumberOfMeasurements(obj)
        value = numel(obj.MeasurementInfo);
    end
    
    function value = get.NumberOfODTs(obj)
        value = numel(obj.ODTObject);
    end
    
end % Custom get/set methods for properties. 
    
end