www.gusucode.com > vnt工具箱matlab源码程序 > vnt/vnt/canMessageImport.m

    function msg = canMessageImport(file, vendor, database)
% canMessageImport Import a CAN message log file.
%
%   MSG = canMessageImport(FILE, VENDOR) reads the input FILE as a 
%   CAN message log file from the specified VENDOR. All message data is
%   converted into MATLAB CAN messages usable by Vehicle Network Toolbox. 
%   These messages are output as the array MSG.
%
%   MSG = canMessageImport(FILE, VENDOR, DATABASE) performs the same 
%   conversion as detailed above; however, when given a handle to a CAN 
%   DATABASE file as input, the DATABASE information is applied to the 
%   converted messages.
%
%   Note that while some vendor's tools log messages in multiple
%   file formats, this import tool only works with specific formats from
%   certain vendors. This includes:
%       Vector - ASCII files.
%       Kvaser - Text files.
%
%   Furthermore, the import function assumes that the information contained
%   in the log files are in hexadecimal format and that timestamps are
%   absolute values. Vector log files with symbolic names for message are 
%   also allowed, but require the use of a database file on import.
%
%   Once a CAN message log file is converted into MATLAB CAN messages, those 
%   messages can be used for analysis, transmit, replay, and so on.
%
%   Examples:
%     Import a message log file as raw messages.
%       msg = canMessageImport('MsgLog.asc', 'Vector')
%
%     Import a message log file using a database for physical messages.
%       db = canDatabase('myDatabase.dbc')
%       msg = canMessageImport('MsgLog.txt', 'Kvaser', db)
%

% Copyright 2009-2015 The MathWorks, Inc.

% Error check input arguments.
narginchk(2, 3);

% Validate the file argument.
if ~ischar(file)
    error(message('vnt:canMessageImport:InvalidFile'));
end

% Validate the vendor argument.
vendor = validatestring(vendor, {'Vector', 'Kvaser'}, 'canMessageImport', 'VENDOR');
vendor = lower(vendor);

% Verify that we have right type of file input depending on the vendor.
[~, ~, fileExt] = fileparts(file);
% Find the file using which.
fullFilePath = which(file);
if strcmp(fullFilePath, '')
    % Find the file using fileattrib.
    [status, info] = fileattrib(file);
    if status
        % Return the full path if fileattrib found the file.
        fullFilePath = info.Name;
    end
end

switch lower(vendor)
    case 'vector'
        % Vector log files must be '.asc' files.
        if ~strcmpi(fileExt, '.asc')
            error(message('vnt:canMessageImport:IncorrectVectorLogFileType'));
        end
        
    case 'kvaser'
        % Kvaser log files must be '.txt' files.
        if ~strcmpi(fileExt, '.txt')
            error(message('vnt:canMessageImport:IncorrectKvaserLogFileType'));
        end
end

% Validate the CAN database argument if one exists.
if nargin == 3
    % The argument must be a object of the can.Database type.
    validateattributes(database, {'can.Database'}, {'nonempty'}, 'canMessageImport', 'DATABASE');
else
    % Set the database reference as empty.
    database = [];
end

% Call to the MEX processing function to parse the log file contents into
% values and types that we can use to convert to CAN message objects.
[status, importedMsgStructs, messageCount] = mexParseCANMessageLogFile(fullFilePath, vendor);

% Handle the error condition if we cannot open the log file.
if status == 1
    error(message('vnt:canMessageImport:UnableToOpenLogFile'));
end

% Check if no messages were actually imported.
if messageCount == 0
    % Return an empty message.
    msg = can.Message.empty();
    return;
end

% If messages are read from the file, we need to create "Name" and
% "Database" fields on the message structures. The structure come back form
% the MEX code with only raw message fields.
importedMsgStructs(end).Database = [];

% The following code is only run for Vector log files. Vector logs may
% contain physical message names instead of just IDs. The MEX code returns
% the ID as "4,294,967,295" and gives the message name when this is encountered 
% in a log file. Now, we need to look up the message information in the
% database.
if strcmpi(vendor, 'vector')
    % Initialize a logical index array of the same size as the number of
    % messages we have parsed.
    toRemoveLogical(numel(importedMsgStructs)) = false;

    % Loop through each message.
    for ii = 1:messageCount
        % Look for the integear maximum value in the ID to indicate this
        % was a message imported with a name.
       if importedMsgStructs(ii).ID == 4294967295
           % Verify that a database is available to use.
           if isempty(database)
                warning(message('vnt:canMessageImport:NoDatabaseProvided', ...
                    importedMsgStructs(ii).Name, ...
                    messageCount));
                % Set this message to be removed from the imported message
                % set. It is invalid without having found the definition in
                % the database.
                toRemoveLogical(ii) = true;
                continue;
           end

            % Look up the message in the database using the name.
            msgInfo = privateMessageInfoByName(database, importedMsgStructs(ii).Name);

            % If the message was not found in the database, we cannot import it.
            if isempty(msgInfo)
                warning(message('vnt:canMessageImport:MessageNameNotFound', ...
                    importedMsgStructs(ii).Name, ...
                    messageCount));
                % Set this message to be removed from the imported message
                % set. It is invalid without having found the definition in
                % the database.
                toRemoveLogical(ii) = true;
                continue;
            end

            % If the message was found, use the information from the 
            % database to set the details.
            importedMsgStructs(ii).ID = msgInfo.ID;
            importedMsgStructs(ii).Extended = msgInfo.Extended;
            importedMsgStructs(ii).Name = msgInfo.Name;
            importedMsgStructs(ii).Database = database;
       end
    end

    % Clear all of the messages that were imported with names, but not
    % found in the database.
    importedMsgStructs(toRemoveLogical) = [];
end

% Check if a database is available to help convert message structures to
% message objects.
if isempty(database)
    % If not, convert using just the raw information.
    msg = can.Message(importedMsgStructs);
else
    % Otherwise, use the database.
    msg = can.Message(importedMsgStructs, database);
end 
end