Accept or reject new ROS 2 action goal and send status
accepts or rejects a new action goal associated with the goal structure
goalStruct that a client sent to the ROS 2 action server
server, based on the specified goal acceptance status
goalStatus. Use this function in the new goal reception callback
function specified to the
ReceiveGoalFcn property of the
Create ROS 2 Action Server and Execute a Goal
This example shows how to create a ROS 2 action server, connect an action client to it, receive a goal, and execute it.
Create a ROS 2 node.
node = ros2node("/node_1");
Set up an action server for calculating Fibbonacci sequence. Specify the goal execution, reception and cancel callbacks.
server = ros2actionserver(node,"/fibbonacci","example_interfaces/Fibonacci",ReceiveGoalFcn=@goalReceptionCB,... ExecuteGoalFcn=@goalExecutionCB,CancelGoalFcn=@cancelGoalCB)
server = ros2actionserver with properties: ActionName: '/fibbonacci' ActionType: 'example_interfaces/Fibonacci' MultiGoalMode: 'on' ExecuteGoalFcn: @goalExecutionCB ReceiveGoalFcn: @goalReceptionCB CancelGoalFcn: @cancelGoalCB GoalServiceQoS: 'History: keeplast, Depth: 10, Reliability: reliable, Durability: volatile' ResultServiceQoS: 'History: keeplast, Depth: 10, Reliability: reliable, Durability: volatile' CancelServiceQoS: 'History: keeplast, Depth: 10, Reliability: reliable, Durability: volatile' FeedbackTopicQoS: 'History: keeplast, Depth: 10, Reliability: reliable, Durability: volatile' StatusTopicQoS: 'History: keeplast, Depth: 1, Reliability: reliable, Durability: transientlocal'
Create an action client and specify a goal message to calculate the Fibbonacci sequence up to 10 terms past the first term
client = ros2actionclient(node,"/fibbonacci","example_interfaces/Fibonacci"); waitForServer(client); goalMsg = ros2message(client); goalMsg.order = int32(10);
Send the goal. Use
ros2ActionSendGoalOptions function to specify callback options when the client receives feedback and result messages from the server.
callbackOpts = ros2ActionSendGoalOptions(FeedbackFcn=@printFeedback,ResultFcn=@printResult); goalHandle = sendGoal(client,goalMsg,callbackOpts);
goalReceptionCB is the goal reception callback that is triggered when the action server receives a new goal. Use the
handleGoalResponse object function to accept or reject a new goal.
function goalReceptionCB(src,goalStruct) fprintf("[Server] Goal received, UUID: %s\n",goalStruct.goalUUID) if goalStruct.goal.order < 1 % Reject Goal handleGoalResponse(src,goalStruct,'REJECT'); else handleGoalResponse(src,goalStruct,'ACCEPT_AND_EXECUTE'); end end
goalExecutionCB is the goal execution callback that is triggered after a new goal is accepted and the server is ready to execute it. In this example, use
goalExecutionCB to calculate the Fibonacci sequence for the number of terms specified in the goal message. First, check whether the client has preempted the goal using the
isPreemptRequested object function. If not, continue goal execution and send periodic feedback to the client about the goal execution status.
function [result,success] = goalExecutionCB(src,goalStruct,defaultFeedbackMsg,defaultResultMsg) fprintf('[Server] Goal accepted and executing, UUID: %s\n', goalStruct.goalUUID); success = true; result = defaultResultMsg; feedback = defaultFeedbackMsg; feedback.sequence = int32([0;1]); for k=1:goalStruct.goal.order-1 % Check that the client has not preempted the goal if isPreemptRequested(src,goalStruct) success = false; break end % Periodically send feedback to the client feedback.sequence = [feedback.sequence; int32(0)]; feedback.sequence(end) = feedback.sequence(end-1) + feedback.sequence(end-2); sendFeedback(src,goalStruct,feedback); end if success result.sequence = feedback.sequence; end end
cancelGoalCB is the cancel goal callback that is triggered after the server receives a cancel request from the client.
function cancelGoalCB(~,goalStruct) fprintf('[Server] Received request to cancel goal with UUID: %s\n', goalStruct.goalUUID); end
printFeedback function is triggered when the client receives the feedback message from the server.
function printFeedback(goalHandle,resp) seq = resp.sequence; fprintf("[Client] Feedback: Fibonacci sequence for goal %s calculated currently: [", goalHandle.GoalUUID); for i=1:numel(seq) fprintf(" %d",seq(i)); end fprintf(' ]\n'); end
printResult function is triggered when the client receives the result message from the server.
function printResult(goalHandle,resp) seq = resp.result.sequence; fprintf("[Client] Result: Fibonacci sequence for goal %s is: [", goalHandle.GoalUUID); for i=1:numel(seq) fprintf(" %d",seq(i)); end fprintf(' ]\n'); end
server — ROS 2 action server
ROS 2 action server, specified as a
goalStruct — Structure containing the goal information
Structure containing the goal information, specified as a ROS 2 action goal
structure. The new goal reception callback function in the
ReceiveGoalFcn property of the
object automatically generates this structure as an input argument. The ROS 2 action
goal structure contains these fields:
goal— Goal message structure
goalUUID— Unique ID of the goal
goalStatus — Goal Acceptance Status
'ACCEPT AND EXECUTE' |
Goal acceptance status, specified as one of these options:
'ACCEPT_AND_EXECUTE'— Accepts the goal for execution and sends the acceptance status to the client. If the ROS 2 action server is in multi-goal mode, the server puts the goal in the queue for execution. If the server is not in multi-goal mode, the server executes the goal immediately.
'REJECT'— Rejects the goal and sends the rejection status to the client.
C/C++ Code Generation
Generate C and C++ code using MATLAB® Coder™.
Introduced in R2023b