Skip to content

User_App_Fibonacci_Action_Server

Mehmet Emre Çakal edited this page Oct 10, 2024 · 6 revisions

Fibonacci Action Server

  1. Requirements
  2. Configure Action Server on Unity3D
  3. Run the Action Client on ROS
  4. About the Server State Machine Model
  5. The Code Explained

0. Requirements

This tutorial assumes that you have completed:

1. Configure Action Server on Unity3D

  • Create a new empty GameObject, name it as 'RosConnector'. This is where we will attach our RosConnector and UnityFibonacciActionServer components.

  • Action Name is the name of the action, set it to "fibonacci". Usually published and subscribed topics are named as 'action_name/goal', 'action_name/feedback', etc.

  • Status and Feedback are the fields to inform users about the current state of action server, and updated by FibonacciActionServer object in accordance with the server state machine model.

  • Simply run the Unity3D application, and then run the action client on the ROS side.

User_App_ROS_UnityActionClient_Inspector

2. Run the Action Client on ROS

  • Note: This section assumes that you have ROS installed on a machine accessible from Unity machine and have rosbridge_server installed in ROS. See our wiki page for installation guide

  • In order to get Unity to talk to ROS, fire up RosBridge WebSocket by running the following in terminal

$ roslaunch rosbridge_server rosbridge_websocket.launch
$ rosrun actionlib_tutorials fibonacci_client

User_App_Actionlib_RosClient

  • You should now see on Unity3D inspector window that status and feedback fields are being updated. Once the goal has succeeded, check back in your ROS machine and see that the client has received a result.

User_App_Actionlib_RosClientSuccess

3. About the Server State Machine Model

Original at: http://wiki.ros.org/actionlib/DetailedDescription?action=AttachFile&do=get&target=server_states_detailed.png

Image from ROS Actionlib Detailed Description

User_App_UnityServer_StateMachine

Transition Representing Method On transition method
Receive Goal private void GoalCallback(actionGoal) protected abstract void OnGoalReceived()
Cancel Request private void CancelCallback(goalID) protected abstract void OnGoalPreempting()
setAccepted protected void SetAccepted() protected abstract void OnGoalActive()
setRejected protected void SetRejected() protected virtual void OnGoalRejected()
setSucceeded protected void SetSucceeded() protected virtual void OnGoalSucceeded()
setCanceled protected void SetCanceled() protected virtual void OnGoalCanceled()

4. The Code Explained

  • ActionServer.cs is an abstract class which can be implemented by providing the message types of the defined ROS action. Please see the example implementation FibonacciActionServer.cs to observe the message types used for Fibonacci action example.
public abstract class ActionServer<TAction, TActionGoal, TActionResult, TActionFeedback, TGoal, TResult, TFeedback>
    where TAction : Action<TActionGoal, TActionResult, TActionFeedback, TGoal, TResult, TFeedback>
    where TActionGoal : ActionGoal<TGoal>
    where TActionResult : ActionResult<TResult>
    where TActionFeedback : ActionFeedback<TFeedback>
    where TGoal : Message
    where TResult : Message
    where TFeedback : Message
    {
        public string status = "";
        public string feedback = "";

        private ManualResetEvent isProcessingGoal = new ManualResetEvent(false);
        private Thread goalHandler;
  • ManualResetEvent isProcessingGoal is used to notify goal processing thread to stop processing the goal.

  • Thread goalHandler is the asynchronous goal handling thread. Goal handling is executed on a separate thread to allow for goal preempting.

  • ActionServer has generic callback functions for subscriptions to 'action_name/goal' and 'action_name/cancel', in which application-specific state transition functions are called.

  • In order to implement ActionServer, users only have to implement these state transition functions, for example, OnGoalReceived() function to process the goal request from the action client.

// When receive a new goal
protected abstract void OnGoalReceived();
private void GoalCallback(TActionGoal actionGoal)
{
    action.action_goal = actionGoal;
    UpdateAndPublishStatus(ActionStatus.PENDING);
    OnGoalReceived();
}
  • FibonacciActionServer object can be instantiated either on Unity3D or in a console application.

  • For the use of action server implementation on Unity3D, please see UnityFibonacciActionServer.cs.

public class UnityFibonacciActionSever : MonoBehaviour
{
    private RosConnector rosConnector;
    private FibonacciActionServer fibonacciActionServer;

    public string actionName;
    public string status;
    public string feedback;

    private void Start()
    {
        rosConnector = GetComponent<RosConnector>();
        fibonacciActionServer = new FibonacciActionServer(actionName, rosConnector.RosSocket, new Log(x => Debug.Log(x)));
        fibonacciActionServer.Initialize();
    }
  • Note that this is a MonoBehaviour class. On Unity3D application start, FibonacciActionServer object is instantiated with an action name, a RosSocket, and a Log delegate.
private void Update()
{
    fibonacciActionServer.PublishStatus();
    status = fibonacciActionServer.GetStatus().ToString();
    feedback = fibonacciActionServer.GetFeedbackSequenceString();
}
  • On every Unity3D update step, we publish the status of the server to ROS and call some getter functions of the server instance to update the fields on the inspector.

  • For the use of action server implementation in a console application, please see FibonacciActionServerConsoleExample.cs.


Next tutorial: Unity application examples without ROS communication


© Siemens AG, 2017-2024

Clone this wiki locally