www.gusucode.com > ros 工具箱 matlab源码程序 > ros/+robotics/+ros/+internal/Global.m
classdef Global %This class is for internal use only. It may be removed in the future. %GLOBAL Functions for handling the global node and global core % MATLAB uses a unique, global ROS node object for each running MATLAB % session. Optionally, MATLAB can also launch a global core. % The robotics.ros.internal.Global class exposes functions that allow the % manipulation of these global entities. % % robotics.ros.internal.Global methods: % core - Initialize or clear the global ROS core object % node - Initialize or clear the global ROS node object % Copyright 2014-2015 The MathWorks, Inc. properties(Access = ?matlab.unittest.TestCase, Constant) %DefaultCorePort - The default port to start the global core DefaultCorePort = 11311 %DefaultNodeName - The default prefix for the global node name DefaultNodeName = 'matlab_global_node_' %DefaultNodeNameDigits - Number of digits that are suffixed to the global node name DefaultNodeNameDigits = 5 %RandomSource - Source of pseudo-random numbers for node name RandomSource = robotics.internal.Random end methods (Static) function masterURI = core( op, port ) %CORE Initialize or clear the global core object % The operation 'op' defines the behavior of this function. % % robotics.ros.internal.Global.core('clear') clears (deletes) the global % core. It will be reinitialized on the next call to ROSINIT or % robotics.ros.internal.Global.core('init') % % robotics.ros.internal.Global.core('init', PORT) % initializes the global ROS core on PORT. This call will fail % if there is another core already running on that port. If % PORT is [], the default of 11311 will be used. switch op case 'clear' robotics.ros.internal.Global.coreInstance('clear'); if nargout > 0 masterURI = []; end case 'init' if isempty(port) port = robotics.ros.internal.Global.DefaultCorePort; end core = robotics.ros.internal.Global.coreInstance('init', ... port); if nargout > 0 masterURI = core.MasterURI; end otherwise error(message('robotics:ros:core:GlobalCoreInvalidOp', op)); end end function node( op, name, masterURI, nodeHost ) %NODE Initialize or clear the global node object % The operation 'op' defines the behavior of this function. % % robotics.ros.internal.Global.node('clear') clears (deletes) the global % node. It will be reinitialized on the next call to ROSINIT or % robotics.ros.internal.Global.node('init') % % robotics.ros.internal.Global.node('init', 'NAME', 'MASTERURI', 'NODEHOST') % initializes the global ROS node. % NAME is a the node name (specify '' if % the default should be used). MASTERURI denotes the Master % URI that the global node should connect to (use '' if the % default should be used). The NODEHOST setting is used by % the node to advertise itself (use '' for default). switch op case 'clear' robotics.ros.internal.Global.nodeInstance('clear'); case 'init' % Always clear existing node robotics.ros.internal.Global.nodeInstance('clear'); % Then re-initialize node robotics.ros.internal.Global.nodeInstance('init', ... name, masterURI, nodeHost); otherwise error(message('robotics:ros:node:GlobalNodeInvalidOp', op)); end end function [active, nodeHandle] = isNodeActive %isNodeActive Check if global node is running or not. try nodeHandle = robotics.ros.internal.Global.getNodeHandle(false); active = true; catch active = false; nodeHandle = []; end end function [active, coreHandle] = isCoreActive %isCoreActive Check if global core is running or not. try coreHandle = robotics.ros.internal.Global.getCoreHandle(false); active = true; catch active = false; coreHandle = []; end end function node = getNodeHandle(init) %getNodeHandle Get instance of the global node node = robotics.ros.internal.Global.nodeInstance; if ~isempty(node) return; end % The global node is not initialized if init % Initialize the node if requested by the caller robotics.ros.internal.Global.node('init', '', '', ''); node = robotics.ros.internal.Global.nodeInstance; else % If user did not request a node start, throw an % appropriate error message error(message('robotics:ros:node:GlobalNodeNotRunning')); end end function core = getCoreHandle(init) %getCoreHandle Get instance of the global node core = robotics.ros.internal.Global.coreInstance; if ~isempty(core) return; end % The global core is not initialized if init % Initialize the core if requested by the caller robotics.ros.internal.Global.core('init', []); core = robotics.ros.internal.Global.coreInstance; else % If user did not request a core start, throw an % appropriate error message error(message('robotics:ros:core:GlobalCoreNotRunning')); end end end methods(Access = private, Static) function n = nodeInstance(op, name, masterURI, nodeHost) persistent node mlock if nargin == 0 n = node; return; end switch op case 'clear' clearNode; case 'init' initNode(name, masterURI, nodeHost); end function initNode(name, masterURI, nodeHost) if isempty(name) name = robotics.ros.internal.Global.DefaultNodeName; nodeCreateFcn = @(n,uri,nhost)robotics.ros.internal.Global.createNodeWithDefaultName(n, uri, 'NodeHost', nhost); else nodeCreateFcn = @(n,uri,nhost)robotics.ros.Node(n, uri, 'NodeHost', nhost); end clearNode; node = nodeCreateFcn(name, masterURI, nodeHost); disp(getString(message('robotics:ros:node:InitializeGlobal', ... node.Name, node.NodeURI))); end function clearNode % Check for the unlikely case that node is already a % deleted handle and recover gracefully. if isobject(node) && ~isvalid(node) node = []; return; end if ~isempty(node) disp(getString(message('robotics:ros:node:ShuttingDownGlobal', ... node.Name, node.NodeURI))); delete(node); node = []; end end end function c = coreInstance(op, port) persistent core mlock if nargin == 0 c = core; return; end switch op case 'init' initCore(port); c = core; case 'clear' clearCore(); return; end function clearCore % Check for the unlikely case that core is already a % deleted handle and recover gracefully. if isobject(core) && ~isvalid(core) core = []; return; end if ~isempty(core) disp(getString(message('robotics:ros:core:ShuttingDownGlobal', ... core.MasterURI))); delete(core); core = []; end end function initCore(port) if isempty(core) core = robotics.ros.Core(port); disp(getString(message('robotics:ros:core:InitializeGlobal', ... core.MasterURI))); return; end % If port number is different, restart core if port ~= core.Port clearCore(); core = robotics.ros.Core(port); disp(getString(message('robotics:ros:core:InitializeGlobal', ... core.MasterURI))); end end end function node = createNodeWithDefaultName(name, varargin) %createNodeWithDefaultName Create the global ROS node with a default name % The input arguments are fed straight into the robotics.ros.Node constructor. nodeCreated = false; % Create random node name % Cycle multiple times in the (very unlikely) case that a node with % the same name already exists. retryMax = 3; retryCount = 0; numDigits = robotics.ros.internal.Global.DefaultNodeNameDigits; while ~nodeCreated % Use a random number as a suffix randNumStr = robotics.ros.internal.Global.RandomSource.timeNumericString(numDigits); try node = robotics.ros.Node([name randNumStr], varargin{:}); catch ex switch ex.identifier case 'robotics:ros:node:NodeNameExists' % This exception occurred because our % random name collides with a name of a % different node. Retry the node creation with % a different random name up to retryMax times. if retryCount == retryMax error(message('robotics:ros:node:DefaultNodeNameError')); end retryCount = retryCount + 1; % Pause for a little bit to ensure that time is % changing. Randomize the wait time between 0.05 and 0.15 % seconds, in case that multiple instances of MATLAB % use the same time base. waitTime = 0.1 + 0.1*(rand-0.5); pause(waitTime); continue; otherwise % Some other exception occurred. rethrow(ex); end end nodeCreated = true; end end end end