www.gusucode.com > ros 工具箱 matlab源码程序 > ros/+robotics/+ros/SimpleActionClient.m
classdef SimpleActionClient < ... robotics.ros.internal.mixin.NodeDependent & ... robotics.ros.internal.mixin.Unsaveable & ... robotics.ros.internal.mixin.JavaAccess & ... handle %SimpleActionClient Create a simple ROS action client % Use SimpleActionClient to connect to an action server and request the % execution of action goals. You can get feedback on the execution % progress and cancel the goal at any time. SimpleActionClient % encapsulates a simple action client and allows you to track a % single goal at a time. % % CLIENT = robotics.ros.SimpleActionClient(NODE, 'ACTIONNAME') creates % a CLIENT for the ROS action with name ACTIONNAME. NODE is the % robotics.ros.Node object that is used to connect to the ROS % network. If an action with this name is available in the % ROS network, the client determines the action type automatically. % If the action is not available, this function displays an error. CLIENT % is a simple action client and allows you to track a single goal at a % time. % % CLIENT = robotics.ros.SimpleActionClient(NODE, 'ACTIONNAME', 'ACTIONTYPE') % creates an action client for the ROS action with name ACTIONNAME and % type ACTIONTYPE. If no action with this name is available in the ROS network, % it is created. If an action with the same name is available, but its % type does not match ACTIONTYPE, the function displays an error. % % % SimpleActionClient properties: % ActionName - Name of action associated with this client (Read-only) % ActionType - Type of action (Read-only) % IsServerConnected - Indicates if client is connected to action server (Read-only) % Goal - The tracked goal (Read-only) % GoalState - State of the tracked goal (Read-only) % ActivationFcn - Function executed on goal activation % FeedbackFcn - Function executed for goal feedback % ResultFcn - Function executed for goal result % % SimpleActionClient methods: % waitForServer - Wait for action server to start % sendGoal - Send goal message to action server % sendGoalAndWait - Send goal message and wait for result % cancelGoal - Cancel last goal this client sent % cancelAllGoals - Cancel all goals on the server % rosmessage - Create goal message % % % Example: % node = robotics.ros.Node('/tbot_client'); % % % Create action client for TurtleBot movement % % The turtlebot_move action server needs to be running % tbot = robotics.ros.SimpleActionClient(node, '/turtlebot_move', 'turtlebot_actions/TurtlebotMove') % % % Wait for the action server to start up % waitForServer(tbot) % % % Request forward movement and wait until the TurtleBot is done % goalmsg = rosmessage(tbot); % goalmsg.ForwardDistance = 1.0; % resultmsg = sendGoalAndWait(tbot, goalmsg); % % % Display the actual distance moved by the robot and the final goal state % resultmsg.ForwardDistance % tbot.GoalState % % % Set a custom callback for goal results. Disable feedback. % tbot.FeedbackFcn = [] % tbot.ResultFcn = @(~,res) disp(['TurtleBot moved ' num2str(res.Message.ForwardDistance) ' meters forward']) % % % Send a goal to the server. This call will return immediately. % sendGoal(tbot, goalmsg); % % See also ROSACTIONCLIENT, ROSACTION. % Copyright 2016 The MathWorks, Inc. properties (SetAccess = private) %ActionName - Name of action associated with this client ActionName = '' %ActionType - Type of action associated with this client ActionType = '' %IsServerConnected - Indicates if client is connected to action server % See also waitForServer. IsServerConnected = false %Goal - The tracked goal % The simple action client tracks the execution of this goal. The % client can only track a single goal at a time. Goal %GoalState - State of the tracked goal % This reflects the state of the goal that is currently tracked % by this action client (last goal message sent to the % action server). % Possible values are: 'pending', 'active', 'recalled', 'rejected', % 'preempted', 'aborted', 'succeeded', or 'lost' GoalState = '' end properties (Dependent) %ActivationFcn - Function executed on goal activation % This function is called when the last sent goal is accepted by % the action server and it transitions into the 'active' state. % % The callback function should accept at least one input % argument, CLIENT, which is the associated SimpleActionClient % object. Additional input arguments can be provided with VARARGIN. % % The function signature is as follows: % % function activationFcn(CLIENT, VARARGIN) % ActivationFcn %FeedbackFcn - Function executed for goal feedback % This function is called at a regular rate during execution of % the last sent goal. The received feedback message contains % information about the goal progress. % % The callback function should accept at least two input % argument. The first argument, CLIENT, is the associated SimpleActionClient % object. The second argument, FBMSG, is the received feedback % message. Additional input arguments can be provided with VARARGIN. % % The function signature is as follows: % % function feedbackFcn(CLIENT, FBMSG, VARARGIN) % % You pass additional arguments to the callback function by including % both the callback function and the arguments as elements of a cell array % when setting the property. FeedbackFcn %ResultFcn - Function executed for goal result % This function is called when the last sent goal finishes % execution on the server and is in a final state. The received % message contains information about the goal result. % % The callback function should accept at least two input % arguments. The first argument, CLIENT, is the associated SimpleActionClient % object. The second argument, RESULT, is a structure with information % about the goal result. Additional input arguments can be provided with VARARGIN. % The RESULT structure contains the following fields: % - Message - Received result message % - State - Final goal state % - StatusText - Status text associated with state % % The function signature is as follows: % % function resultFcn(CLIENT, RESULT, VARARGIN) % % You pass additional arguments to the callback function by including % both the callback function and the arguments as elements of a cell array % when setting the property. ResultFcn end properties (Access = ?matlab.unittest.TestCase) %JavaActionClient - Simple action client Java object JavaActionClient end properties (Access = private) %ClientCallbacks - Java object handling callbacks from action client % This object is passed to Java calls to sendGoal and % sendGoalAndWait and acts as an intermediary between Java % and MATLAB callback functions. ClientCallbacks %ActivationListener - Bound listener object for activation notices ActivationListener %FeedbackListener - Bound listener object for received goal feedback FeedbackListener %ResultListener - Bound listener object for received goal result ResultListener %InternalActivationFcn - Internal storage for the ActivationFcn callback InternalActivationFcn %InternalFeedbackFcn - Internal storage for the FeedbackFcn callback InternalFeedbackFcn %InternalResultFcn - Internal storage for the ResultFcn callback InternalResultFcn %GoalMessageType - The message type of the goal message (sent by client) GoalMessageType %FeedbackMessageType - The message type of the feedback message (sent by server) FeedbackMessageType %ResultMessageType - The message type of the result message (sent by server) ResultMessageType end properties (Access = ?matlab.unittest.TestCase) %Delegate - The delegate for most ROS-related functionality Delegate %Parser - Helper object for parsing tasks Parser end methods function obj = SimpleActionClient(node, actionNamespace, varargin) %SimpleActionClient Create a ROS action client object % See also SimpleActionClient. narginchk(2,3); % Assign the delegates for most action client business logic delegateFactory = robotics.ros.internal.action.ActionDelegateFactory.getInstance; clientDelegate = delegateFactory.findDelegate('simpleClientDelegate'); parser = delegateFactory.findDelegate('simpleClientParser'); % Figure out if we need to use the global node or not node = clientDelegate.checkGlobalNode(node); % Parse the input arguments defaultActionType = ''; [node, actionNamespace, actionType] = ... parser.parseConstructorInput(defaultActionType, node, actionNamespace, varargin{:}); % Construct superclass obj = obj@robotics.ros.internal.mixin.NodeDependent(node); obj.Delegate = clientDelegate; obj.Parser = parser; [obj.ActionName, obj.ActionType] = obj.Delegate.resolveNameType( ... node, actionNamespace, actionType, defaultActionType); obj.GoalMessageType = [obj.ActionType 'Goal']; obj.FeedbackMessageType = [obj.ActionType 'Feedback']; obj.ResultMessageType = [obj.ActionType 'Result']; % Create Java action client and initial goal message obj.JavaActionClient = obj.Delegate.createActionClient(node.JavaNode, obj.ActionName, obj.ActionType); goalMsg = obj.Delegate.createGoalMessage(obj.GoalMessageType); obj.Goal = goalMsg.empty(0,1); % Initialize callback functions obj.ClientCallbacks = com.mathworks.toolbox.robotics.ros.action.SimpleActionClientCallbacks; [obj.ActivationListener, obj.FeedbackListener, obj.ResultListener] = ... obj.Delegate.attachEventListeners(obj.ClientCallbacks); % Set default callback functions obj.FeedbackFcn = []; obj.ResultFcn = []; obj.ActivationFcn = []; obj.FeedbackFcn = obj.defaultFeedbackFcn; obj.ResultFcn = obj.defaultResultFcn; obj.ActivationFcn = obj.defaultActivationFcn; end function delete(obj) %DELETE Shut down action client % DELETE(CLIENT) shuts down the ROS action client object CLIENT. % If the goal that was last sent to the action server is active, % it is not cancelled. if ~isempty(obj.Delegate) obj.Delegate.shutdown(obj.JavaActionClient); end end function goalMsg = rosmessage(obj) %ROSMESSAGE Create goal message based on action type % GOALMSG = ROSMESSAGE(CLIENT) creates and returns a new goal % message GOALMSG. The message type of GOALMSG is determined % by the action type associated with this action client. % % Example: % % Create action client and goal message % fibclient = robotics.ros.SimpleActionClient(node, '/fibonacci'); % goalmsg = ROSMESSAGE(fibclient); goalMsg = obj.Delegate.createGoalMessage(obj.GoalMessageType); end function waitForServer(obj, varargin) %waitForServer Wait for action server to start % waitForServer(CLIENT) blocks MATLAB from running the current program % until the action server is started up and available to % receive goals. Press Ctrl+C to abort the wait. % % waitForServer(CLIENT, TIMEOUT) specifies a TIMEOUT period, in % seconds. If the server does not start up in the timeout % period, this function displays an error. narginchk(1,2); defaultTimeout = Inf; timeout = obj.Parser.parseWaitForServerInput(defaultTimeout, varargin{:}); isConnected = obj.Delegate.waitForServer(obj.JavaActionClient, timeout); if ~isConnected error(message('robotics:ros:actionclient:WaitServerTimeout', num2str(timeout))); end end function sendGoal(obj, goalMsg) %sendGoal Send goal message to action server % sendGoal(CLIENT, GOALMSG) sends a goal message object, % GOALMSG, to the action server. This goal is tracked by % the action client. The function does not wait % for the goal to be executed and returns immediately. % If the ActivationFcn, FeedbackFcn, and ResultFcn callbacks % are defined, they are called when the goal is processing on % the action server. % All callbacks associated with a previously sent goal are % disabled, but the previous goal is not cancelled. % % See also sendGoalAndWait, ResultFcn, FeedbackFcn, ActivationFcn. obj.Parser.parseSendGoalInput(goalMsg, obj.GoalMessageType); obj.Goal = goalMsg; obj.Delegate.sendGoal(obj.JavaActionClient, goalMsg, obj.ClientCallbacks); end function cancelGoal(obj) %cancelGoal Cancel last goal this client sent % cancelGoal(CLIENT) sends a cancel request for the tracked goal % (last sent to the action server). % If the goal is in the 'active' state, the server preempts % its execution. If the goal is in the 'pending' state, the goal % is recalled. % If no goal has been sent by this CLIENT or if the tracked goal % has finished execution, this function returns immediately. obj.Delegate.cancelGoal(obj.JavaActionClient); end function cancelAllGoals(obj) %cancelAllGoals Cancel all goals on the server % cancelAllGoals(CLIENT) sends a request to the action server % to cancel all currently pending or active goals. This % includes goals from other action clients. obj.Delegate.cancelAllGoals(obj.JavaActionClient); end function [resultMsg, state, statusText] = sendGoalAndWait(obj, goalMsg, varargin) %sendGoalAndWait Send goal message and wait for result % RESULTMSG = sendGoalAndWait(CLIENT, GOALMSG) sends a goal message % object, GOALMSG, to the action server and blocks MATLAB % from running the current program until the action server % returns the result, RESULTMSG. % Press Ctrl+C to abort the wait. % % RESULTMSG = sendGoalAndWait(CLIENT, GOALMSG, TIMEOUT) specifies % a TIMEOUT period, in seconds. If the server does not return % the result in the timeout period, the function displays an % error. % % [RESULTMSG, STATE, STATUSTEXT] = ____ also returns the % final goal state, STATE, and the associated status text, % STATUSTEXT. STATE contains information if the goal % execution succeeded or not. % % If the ActivationFcn, FeedbackFcn, and ResultFcn callbacks % are defined, they are called when the goal is processing on % the action server. narginchk(2,3); % Parse the inputs defaultTimeout = Inf; timeout = obj.Parser.parseSendGoalAndWaitInput(defaultTimeout, obj.GoalMessageType, ... goalMsg, varargin{:}); obj.Goal = goalMsg; [goalDone, resultMsg, state, statusText] = obj.Delegate.sendGoalAndWait(... obj.JavaActionClient, goalMsg, obj.ClientCallbacks, timeout, obj.ResultMessageType); if ~goalDone error(message('robotics:ros:actionclient:WaitGoalTimeout', num2str(timeout))); end end end %% Custom Getters and Setters for Properties methods function isConnected = get.IsServerConnected(obj) isConnected = obj.Delegate.isServerConnected(obj.JavaActionClient); end function state = get.GoalState(obj) state = obj.Delegate.getGoalState(obj.JavaActionClient); end function feedbackFcn = get.FeedbackFcn(obj) feedbackFcn = obj.InternalFeedbackFcn; end function set.FeedbackFcn(obj, fcnHandle) %set.FeedbackFcn Setter for FeedbackFcn callback property if isempty(fcnHandle) % Allow empty input to disable the callback obj.FeedbackListener.Callback = []; obj.InternalFeedbackFcn = []; return; end % Make sure this is a valid function handle and parse any user data [funcHandle, userData] = obj.Parser.parseFcnSetterInput(fcnHandle, 'FeedbackFcn'); obj.FeedbackListener.Callback = {@robotics.ros.internal.action.ActionCallbacks.onActionFeedbackCallback, ... obj, obj.FeedbackListener, obj.FeedbackMessageType, funcHandle, userData}; obj.InternalFeedbackFcn = fcnHandle; end function resultFcn = get.ResultFcn(obj) resultFcn = obj.InternalResultFcn; end function set.ResultFcn(obj, fcnHandle) %set.ResultFcn Setter for ResultFcn callback property if isempty(fcnHandle) % Allow empty input to disable the callback obj.ResultListener.Callback = []; obj.InternalResultFcn = []; return; end % Make sure this is a valid function handle and parse any user data [funcHandle, userData] = obj.Parser.parseFcnSetterInput(fcnHandle, 'ResultFcn'); obj.ResultListener.Callback = {@robotics.ros.internal.action.ActionCallbacks.onActionResultCallback, ... obj, obj.ResultListener, obj.ResultMessageType, funcHandle, userData}; obj.InternalResultFcn = fcnHandle; end function activationFcn = get.ActivationFcn(obj) activationFcn = obj.InternalActivationFcn; end function set.ActivationFcn(obj, fcnHandle) %set.ActivationFcn Setter for ActivationFcn callback property if isempty(fcnHandle) % Allow empty input to disable the callback obj.ActivationListener.Callback = []; obj.InternalActivationFcn = []; return; end % Make sure this is a valid function handle and parse any user data [funcHandle, userData] = obj.Parser.parseFcnSetterInput(fcnHandle, 'ActivationFcn'); obj.ActivationListener.Callback = {@robotics.ros.internal.action.ActionCallbacks.onActionActivationCallback, ... obj, obj.ActivationListener, funcHandle, userData}; obj.InternalActivationFcn = fcnHandle; end end methods (Access = protected) function onNodeShutdownComplete(obj, ~, ~) %onNodeShutdownComplete Called when the Java node finishes shut down % This callback is triggered when the node that this % action client is attached to shuts down. % Set property to empty, so that delete function finishes cleanly % cleanly. obj.JavaActionClient = []; obj.delete; end end methods (Static, Access = ?matlab.unittest.TestCase) function fcn = defaultActivationFcn %defaultActivationFcn Default initialization for ActivationFcn fcn = @(~) disp('Goal active'); end function fcn = defaultFeedbackFcn %defaultFeedbackFcn Default initialization for FeedbackFcn fcn = @(~,msg) disp(['Feedback: ', showdetails(msg)]); end function fcn = defaultResultFcn %defaultResultFcn Default initialization for ResultFcn fcn = @(~,res) disp(['Final state ' res.State ' with result: ' ... showdetails(res.Message)]); end end end