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