Main Content

rosactionserver

Create ROS Action Server

Description

Use rosactionserver to create an action server as a SimpleActionServer object. Then, use the rosactionclient object to create an action client and connect to the action server to request the execution of action goals. When a connected client sends a goal execution request, the server executes the specified callback function. You can use the rosActionServerExecuteGoalFcn function to customize the callback function based on a predefined framework. The server can provide periodic feedback on execution progress to the clients, and stop goal execution if specified or if a new goal is received.

When you create the action server, it registers itself with the ROS master. To get a list of actions, or to get information about a particular action that is available on the current ROS network, use the rosaction function.

An action is defined by a type and three messages: one for the goal, one for the feedback, and one for the result. On receiving a goal, the server goal execution callback must periodically send feedback to the client during goal execution, and return an appropriate result when goal execution completes. The behavior of the action server is inherently asynchronous because it becomes active only when an action client connects to the ROS network and issues a goal execution request.

Creation

Description

example

server = rosactionserver(actionname,actiontype,ExecuteGoalFcn=cb) creates an action server object, server, that corresponds to the ROS action of the specified name, actionname and type, actiontype. You must also specify the ExecuteGoalFcn property as a function handle callback, cb, which handles the goal execution when the client sends a request.

[server] = rosactionserver(___,"DataFormat","struct") specifies to use message structures instead of objects, in addition to all input arguments from the previous syntax. For more information, see Improve Performance of ROS Using Message Structures.

server = ros.SimpleActionServer(node, actionname,actiontype,ExecuteGoalFcn=cb) attaches the created action server to the specified ROS node node.

[server] = ros.SimpleActionServer(___,DataFormat="struct") uses message structures instead of objects. For more information, see Improve Performance of ROS Using Message Structures.

Properties

expand all

This property is read-only.

Name of the action, specified as a string scalar or character vector.

Example: "/fibonacci"

Data Types: char | string

This property is read-only.

Type of action, specified as a string scalar or character vector.

Example: "actionlib_tutorials/Fibonacci"

Data Types: char | string

Action callback function, specified as a function handle or cell array. In the first element of the cell array, specify either a function handle, string scalar, or character vector representing a function name. In subsequent elements, specify user data. To get a predefined framework to customize the callback function, use rosActionServerExecuteGoalFcn.

The action callback function requires at least four input arguments with one output. The first argument, src, is the associated action server object. The second argument, goal, is the goal message sent by the action client. The third argument is the default response message, defaultFeedback. The fourth argument is the default result message, defaultResultMsg. The callback returns a result message, result, based on the input goal message and sends it back to the action client. Use the default response message as a starting point for constructing the request message. The callback also returns success as true if the goal was successfully reached, or as false if the goal was aborted or preempted by another goal. The function header for the callback is:

function [result,success] = actionCallback(src,goalMsg,defaultFeedbackMsg,defaultResultMsg)

Specify the ExecuteGoalFcn property while creating the action server using the name-value pair as:

server = rosactionserver(actionname,actiontype,ExecuteGoalFcn=@actionCallback)

When setting the callback, you pass additional parameters to the callback function by including both the callback function and the parameters as elements of a cell array. The function header for such a callback is:

function [result,success] = actionCallback(src,goalMsg,defaultFeedbackMsg,defaultResultMsg,userData)

Specify the ExecuteGoalFcn property while creating the action server using the name-value pair as:

server = rosactionserver(actionname,actiontype,ExecuteGoalFcn={@actionCallback,userData})

Message format, specified as "object" or "struct". You must set this property on creation using the name-value input. For more information, see Improve Performance of ROS Using Message Structures.

Object Functions

getFeedbackMessageCreate new action feedback message
isPreemeptRequestedCheck if a goal has been preempted
sendFeedbackSend feedback to action client during goal execution

Examples

collapse all

This example shows how to create a ROS action server, connect an action client to it, receive goal, and execute it.

Connect to a ROS network.

rosinit
Launching ROS Core...
Done in 0.41354 seconds.
Initializing ROS master on http://172.29.199.134:56448.
Initializing global node /matlab_global_node_87825 with NodeURI http://dcc664524glnxa64:44009/ and MasterURI http://localhost:56448.

Set up an action server for calculating Fibonacci sequence. Use structures for the ROS message data format. Use fibbonacciExecution function as the callback.

cb = @fibonacciExecution; 
server = rosactionserver("/fibonacci","actionlib_tutorials/Fibonacci",ExecuteGoalFcn=cb,DataFormat="struct")
server = 
  SimpleActionServer with properties:

        ActionName: '/fibonacci'
        ActionType: 'actionlib_tutorials/Fibonacci'
    ExecuteGoalFcn: @fibonacciExecution
        DataFormat: 'struct'

Create action client and send a goal to the server to calculate the Fibonacci sequence up to 10 terms past the first two terms, 0 and 1. Display the result sequence.

client = rosactionclient("/fibonacci","actionlib_tutorials/Fibonacci",DataFormat="struct");
goal = rosmessage(client);
goal.Order = int32(10);
result = sendGoalAndWait(client,goal);
result.Sequence
ans = 12x1 int32 column vector

    0
    1
    1
    2
    3
    5
    8
   13
   21
   34
      ⋮

Shut down ROS network.

rosshutdown
Shutting down global node /matlab_global_node_87825 with NodeURI http://dcc664524glnxa64:44009/ and MasterURI http://localhost:56448.
Shutting down ROS master on http://172.29.199.134:56448.

Supporting Functions

The callback function fibbonacciExecution is executed every time the server receives a goal execution request from the client. This function checks if the goal has been preempted, executes the goal and sends feedback to the client during goal execution.

function [result,success] = fibonacciExecution(src,goal,defaultFeedback,defaultResult)

    % Initialize variables
    success = true;
    result = defaultResult;
    feedback = defaultFeedback;
    feedback.Sequence = int32([0 1]);

    for k = 1:goal.Order
        % Check that the client has not canceled or sent a new goal
        if isPreemptRequested(src)
            success = false;
            break
        end

        % Send feedback to the client periodically
        feedback.Sequence(end+1) = feedback.Sequence(end-1) + feedback.Sequence(end);
        sendFeedback(src,feedback)
        
        % Pause to allow time to complete other callbacks (like client feedback)
        pause(0.2)
    end

    if success
        result.Sequence = feedback.Sequence;
    end

end

This example shows how to create a custom callback for a ROS action server using rosActionServerExecuteGoalFcn, which provides a customizable predefined callback framework.

Connect to a ROS network.

rosinit
Launching ROS Core...
Done in 0.43512 seconds.
Initializing ROS master on http://172.29.209.44:50115.
Initializing global node /matlab_global_node_69468 with NodeURI http://dcc741990glnxa64:44595/ and MasterURI http://localhost:50115.

Set up an action server callback for calculating the Fibonacci sequence using rosActionServerExecuteGoalFcn. Specify the custom callback functions for the tasks in the callback framework. All the callback functions use a shared object to store data. For definition of these custom functions, see Supporting Functions.

% Store the first two terms 0 and 1 in shared object
fibSequence = int32([0 1]);
% Create the callback
cb = rosActionServerExecuteGoalFcn(IsGoalReachedFcn=@isGoalReached,...
        StepExecutionFcn=@nextFibNumber,...
        CreateFeedbackFcn=@assignUserDataToMessage,...
        CreateSuccessfulResultFcn=@assignUserDataToMessage,...
        StepDelay=0.2,...
        UserData=fibSequence);

Use the created custom callback, cb and set up an action server for calculating Fibonacci sequence. Use structures for the ROS message data format.

server = rosactionserver("/fibonacci","actionlib_tutorials/Fibonacci",ExecuteGoalFcn=cb,DataFormat="struct");

Create action client and send a goal to the server, which calculates the first 10 terms in the Fibonacci sequence. Display the result sequence.

client = rosactionclient("/fibonacci","actionlib_tutorials/Fibonacci",DataFormat="struct");
goal = rosmessage(client);
goal.Order = int32(10);
result = sendGoalAndWait(client,goal);
result.Sequence
ans = 10x1 int32 column vector

    0
    1
    1
    2
    3
    5
    8
   13
   21
   34

Shut down ROS network.

rosshutdown
Shutting down global node /matlab_global_node_69468 with NodeURI http://dcc741990glnxa64:44595/ and MasterURI http://localhost:50115.
Shutting down ROS master on http://172.29.209.44:50115.

Supporting Functions

The function isGoalReached checks whether the goal is reached. In this case, it checks whether the number of terms in the calculated Fibonacci sequence exceeds the goal from the client.

function status = isGoalReached(sharedObj,goal) 
    status = numel(sharedObj.UserData) >= goal.Order;
end

The function nextFibNumber is the step execution function that calculates the next term in the sequence in every iteration towards goal execution.

function nextFibNumber(sharedObj,~)
    sharedObj.UserData(end+1) = sharedObj.UserData(end-1) + sharedObj.UserData(end);
end

The function assignUserDataToMessage assigns the current sequence to the appropriate field in the result message. In this specific case of Fibonacci action, the feedback message also uses the same field, Sequence as the result message. Hence, this function can be used for both creating a feedback message and result message to the client.

function msg = assignUserDataToMessage(sharedObj,msg)
    msg.Sequence = sharedObj.UserData;
end

Version History

Introduced in R2022a