www.gusucode.com > ros 工具箱 matlab源码程序 > ros/rosmsg.m

    function output = rosmsg( op, varargin )
%ROSMSG Retrieve information about messages and message types
%   MSGINFO = ROSMSG('show', 'TYPE') prints out the definition of the 
%   message with TYPE. If the output argument MSGINFO is defined, return 
%   the information as a string. Simplified form: ROSMSG show TYPE
%
%   MSGMD5 = ROSMSG('md5', 'TYPE') prints out the MD5 checksum of the 
%   message with TYPE. If the output argument MSGMD5 is defined, return the 
%   checksum as a string. Simplified form: ROSMSG md5 TYPE
%
%   MSGLIST = ROSMSG('list') lists all available message types
%   that can be used in MATLAB. If the output argument MSGLIST is defined,
%   return the list of message types as a cell array of strings.
%   Simplified form: ROSMSG list
%
%
%   Example:
%      % List all available message types
%      ROSMSG list
%
%      % Retrieve message definition of the sensor_msgs/Image type
%      msgInfo = ROSMSG('show', 'sensor_msgs/Image')

%   Copyright 2014-2015 The MathWorks, Inc.

try
    if nargout == 0
        rosmsgImpl(op, varargin{:});
    else
        output = rosmsgImpl(op, varargin{:});
    end
catch ex
    % Save stack traces and exception causes internally, but do not
    % print them to the console
    rosex = robotics.ros.internal.ROSException.fromException(ex);
    throwAsCaller(rosex);
end
end

function output = rosmsgImpl(op, varargin)
%rosmsgImpl Actual implementation of rosmsg functionality

persistent parser
if isempty(parser)
    parser = inputParser;
    addRequired(parser, 'op', @(x) validateattributes(x, {'char'}, {'nonempty'}, 'rosmsg', 'op'));
    addOptional(parser, 'type', '', @(x) validateattributes(x, {'char'}, {'nonempty'}, 'rosmsg', 'type'));
end
parse(parser, op, varargin{:});

operation = parser.Results.op;
messageType = parser.Results.type;

switch(lower(operation))
    case {'info', 'show'}
        % Print out or return message definition information.
        
        msgDef = rosmsgShow( messageType );
        if nargout == 0
            disp(msgDef);
        else
            output = msgDef;
        end
        return;
        
    case 'list'
        % List of messages is retrieved from available message types in the
        % rostype class.
        
        msgs = rosmsgList;
        
        if nargout == 0
            cellStringPrint(msgs);
        else
            output = msgs;
        end
        
        return;
        
    case 'md5'
        % Print out or return message MD5 checksum
        
        msgMD5 = rosmsgMD5( messageType );
        if nargout == 0
            disp(msgMD5);
        else
            output = msgMD5;
        end
        return;
        
    otherwise
        error(message('robotics:ros:node:OperationNotSupported', ...
            operation));
end

end

function msgDef = rosmsgShow(messageType)
%rosmsgShow Retrieve the message definition for a type

persistent nodeConfig
if isempty(nodeConfig)
    fac = robotics.ros.internal.NodeConfigurationFactory;
    nodeConfig = fac.newPrivate;
end

% Display message information
try
    msgDef = char(com.mathworks.toolbox.robotics.ros.message.MessageInfo.getDefinition(nodeConfig, messageType));
    
    % Replace all property names with their MATLAB property equivalent
    reg = robotics.ros.msg.internal.MessageRegistry.getInstance;
    msgClass = reg.getClass(messageType);
    propList = eval([msgClass '.PropertyList']);
    rosPropList = eval([msgClass '.ROSPropertyList']);

    % Use regular expression to replace property names
    for i = 1:numel(rosPropList)
        msgDef = regexpSelective(msgDef, rosPropList{i}, propList{i});
    end
    
    % Make sure to replace all constants, since they are not part of the
    % message's property list. Since it's less likely that other text
    % elements would start with a series of uppercase letters, followed by
    % an underscore and followed by another series of uppercase letters, we
    % can make this replacement more lenient (not referenced to the
    % beginning of a line).
    msgDef = regexprep(msgDef, '([A-Z]+)[_]([A-Z]*[\s\n#])', '$1$2');
    
    % Convert ROS message types to MATLAB data types
    % Replace all deprecated data types
    msgDef = regexpBeginningOfLine(msgDef, 'char', 'uint8');
    msgDef = regexpBeginningOfLine(msgDef, 'byte', 'int8');
    
    % Replace all common primitive data types
    msgDef = regexprep(msgDef, 'float32', 'single');
    msgDef = regexprep(msgDef, 'float64', 'double');
    msgDef = regexpBeginningOfLine(msgDef, 'bool', 'logical');
    msgDef = regexpBeginningOfLine(msgDef, 'string', 'char');
    msgDef = regexpSelective(msgDef, 'time', 'Time');
    msgDef = regexpSelective(msgDef, 'duration', 'Duration');
    msgDef = regexpBeginningOfLine(msgDef, 'Header', 'std_msgs/Header');
    
    % Align all comments that don't start in the first column
    % First, find the maximum column of all comments
    strLines = strsplit(msgDef, '\n')';
    strfind(strLines, '#');
    commentLocation = cell2mat(regexp(strLines, '(?m)^[^#]+#', 'end'));
    maxLoc = max(commentLocation);

    % Second, align all comments with the maximum column
    if ~isempty(maxLoc)
        msgDef = regexprep(msgDef, '(?m)^([^#\n]+)#', '$1${repmat('' '', 1, (maxLoc-length($1)-1))}%');
    end
    
    % Replace all remaining comment characters
    msgDef = regexprep(msgDef, '#', '%');
    
catch ex
    newEx = robotics.ros.internal.ROSException( ...
        message('robotics:ros:message:DefinitionNotFound', messageType));
    throw(newEx.addCustomCause(ex));
end

end

function newString = regexpBeginningOfLine(oldString, expression, replace)
%regexpBeginningOfLine Match and replace a string at the beginning of line
%   This also ignores any whitespace characters that might be in front of
%   the expression.
%   The token $1 ensures that all the white spaces that were matched before
%   EXPRESSION are preserved in the replacement string.
newString = regexprep(oldString, ['(?m)(^\s*)' expression], ['$1' replace]);
end

function newString = regexpSelective(oldString, expression, replace)
%regexpSelective Match and replace a string more liberally
%   As long as the string is surrounded by white spaces or some other
%   calculation signs, or quotation marks, this match will work.
newString = regexprep(oldString, ['(?m)([-#\(+*/"\s]|^)' expression '([-.,:\)=+*/"#\n\s]|$)'], ['$1' replace '$2']);
end

function msgMD5 = rosmsgMD5(messageType)
%rosmsgMD5 Retrieve the message MD5 checksum for a type

persistent topicDescriptionFactory
if isempty(topicDescriptionFactory)
    fac = robotics.ros.internal.NodeConfigurationFactory;
    nodeConfig = fac.newPrivate;
    topicDescriptionFactory = nodeConfig.getTopicDescriptionFactory;
end

try
    descr = topicDescriptionFactory.newFromType(messageType);
    msgMD5 = char(descr.getMd5Checksum);
catch ex
    newEx = robotics.ros.internal.ROSException( message( ...
        'robotics:ros:message:DefinitionNotFound', messageType));
    throw(newEx.addCustomCause(ex));
end
end

function msgList = rosmsgList
%rosmsgList Get a list of all available message types

msgList = rostype.getMessageList;
end

function cellStringPrint(list)
%cellStringPrint Print a cell array of strings to the console

for item = list
    disp(char(item));
end
end