-
Notifications
You must be signed in to change notification settings - Fork 376
User_App_Fibonacci_Action_Server
Note: This tutorial assumes that you have completed:
- Installation and Configuration
- Writing a Simple Action Client (Humble) (Noetic)
- How to add new Message Types
- Configure Action Server on Unity
- Run the Action Client on ROS
- The Code Explained
ROS2 Humble
-
Create a new empty
GameObject
, name it as 'RosConnector'. This is where we will attach ourRosConnector
andUnityFibonacciActionServer
components.- Or you can head to the
Unity Package Manager
window and under theSamples
section of ROS# you can import theFibonacci Action Scene
. For the sake of this tutorial, disable the client component underRosConnector
.
- Or you can head to the
-
Action Name
is the name of the action, set it to "/fibonacci". -
Status
andFeedback
are the fields to inform users about the current state of action server, and updated byFibonacciActionServer
object in accordance with the server state machine model. -
Simply run the Unity application, and then run the action client on the ROS side.
-
Run RosBridge Websocket and the Fibonacci Action Client example from the ROS2 tutorials package action_tutorials_page. The package can be installed using the package manager
sudo apt install ros-humble-action-tutorials-cpp
or from the ROS2 tutorial page: Writing an Action Server and Client (C++). -
Note that to be able to cancel actions, the
send_action_goals_in_new_thread
parameter of the websocket should be set. -
Although there is also a Python version of the tutorial package from the ROS2 documentation, we recommend using the C++ package because there are some bugs with the Python package that make it unable to cancel actions and crash rqt.
ros2 run rosbridge_server rosbridge_websocket --ros-args -p send_action_goals_in_new_thread:=true
# Another terminal
ros2 run action_tutorials_cpp fibonacci_action_client
- Alternatively, you can enable both the client and the server in the Unity scene without using the
action_tutorials_cpp
. But therosbridge_server
must be running in any case.
The FibonacciActionServer.cs
is a derived client implementation of the generic abstract class ActionServer.cs
. In ROS#, each action server and client must implement their respective abstract classes. For more information about the Fibonacci Action server implementation, see .NET Fibonacci Action Client/Server. For more information about the under-the-hood abstract classes and state machine model, see Actions Middleware Implementation, and Action Server State Machine Model, respectively. In this subsection, only the Unity usage example of the Fibonacci Action Server is discussed.
private void Start()
{
rosConnector = GetComponent<RosConnector>();
fibonacciActionServer = new FibonacciActionServer(actionName, rosConnector.RosSocket, new Log(x => Debug.Log(x)));
fibonacciActionServer.Initialize();
}
To create a client instance, a RosSocket
instance, the action name, and a logger function must be passed to the constructor. The action name is not the same as the action message type, it is just a custom name. Message types are handled under the hood. Console.Log
is used as the logger function in this example.
private void Update()
{
status = fibonacciActionServer.GetStatus().ToString();
feedback = fibonacciActionServer.GetFeedbackSequenceString();
}
Although not necessary, status, feedback can be stored in the update loop for monitoring. These values are already handled and sent within the server implementation by their corresponding callback functions. For more information, see Actions Middleware Implementation.
ROS1 Noetic
-
Create a new empty
GameObject
, name it as 'RosConnector'. This is where we will attach ourRosConnector
andUnityFibonacciActionServer
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
andFeedback
are the fields to inform users about the current state of action server, and updated byFibonacciActionServer
object in accordance with the server state machine model. -
Simply run the Unity3D application, and then run the action client on the ROS side.
-
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
- Then get Fibonacci client from ROS tutorial "Writing a Simple Action Client" running by executing the following in a separate terminal window:
$ rosrun actionlib_tutorials fibonacci_client
- 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.
- In Actionlib Detailed Description, ROS defines the action server with the following state machine model:
Image from ROS Actionlib Detailed Description
-
ActionServer.cs
implements the state machine model above. (See Action Server State Machine Model and Action Middleware Implementation for details). For this example, we will only implement the following simplified state machine:
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() |
-
ActionServer.cs
is an abstract class which can be implemented by providing the message types of the defined ROS action. Please see the example implementationFibonacciActionServer.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-2025
-
- 1.3.1 R2D2 Setup
- 1.3.2 Gazebo Setup on VM
- 1.3.3 TurtleBot Setup (Optional for ROS2)
- 2.1 Quick Start
- 2.2 Transfer a URDF from ROS to Unity
- 2.3 Transfer a URDF from Unity to ROS
- 2.4 Unity Simulation Scene Example
- 2.5 Gazebo Simulation Scene Example
- 2.6 Fibonacci Action Client
- 2.7 Fibonacci Action Server
- 3.1 Import a URDF on Windows
- 3.2 Create, Modify and Export a URDF Model
- 3.3 Animate a Robot Model in Unity
- 4.1 Introduction to RosBridgeClient
- 4.2 Image Publication
- 4.3 URDF Transfer
- 4.4 Fibonacci Action Client/Server
- Message Handling: Readers & Writers
- Thread Safety for Message Reception
- File Server Package
- ROS-Unity Coordinate System Conversions
- Post Build Events
- Preprocessor Directives in ROS#
- Adding New Message Types
- RosBridgeClient Protocols
- RosBridgeClient Serializers
- Actions in ROS#
- Action Server State Machine Model
© Siemens AG, 2017-2025