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