Main Content

isPreemptRequested

Check if a goal has been preempted

Since R2023b

Description

example

status = isPreemptRequested(server) checks whether the goal currently being executed by the ROS 2 action server, server, has been preempted and returns the status accordingly. The action client connected to server initiates the goal preemption either by cancelling the current goal.

Examples

collapse all

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, Deadline: Inf, Lifespan: Inf, Liveliness: automatic, Lease Duration: Inf'
    ResultServiceQoS: 'History: keeplast, Depth: 10, Reliability: reliable, Durability: volatile, Deadline: Inf, Lifespan: Inf, Liveliness: automatic, Lease Duration: Inf'
    CancelServiceQoS: 'History: keeplast, Depth: 10, Reliability: reliable, Durability: volatile, Deadline: Inf, Lifespan: Inf, Liveliness: automatic, Lease Duration: Inf'
    FeedbackTopicQoS: 'History: keeplast, Depth: 10, Reliability: reliable, Durability: volatile, Deadline: Inf, Lifespan: Inf, Liveliness: automatic, Lease Duration: Inf'
      StatusTopicQoS: 'History: keeplast, Depth: 1, Reliability: reliable, Durability: transientlocal, Deadline: Inf, Lifespan: Inf, Liveliness: automatic, Lease Duration: Inf'

Create an action client and specify a goal message to calculate the Fibbonacci sequence up to 10 terms past the first term 0.

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);

Supporting Functions

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

Input Arguments

collapse all

ROS 2 action server, specified as a ros2actionserver object handle.

Output Arguments

collapse all

Status of goal preemption, retuned as a logical scalar. If the goal has been preempted, the function returns the status as true.

Extended Capabilities

C/C++ Code Generation
Generate C and C++ code using MATLAB® Coder™.

Version History

Introduced in R2023b