ROS Actions are defined in action/*.action files. For each action ROS requires to have 3 separate messages: Goal, Feedback, Result (see ROS documentation for defining action in ROS2 or ROS1). On top of that ROS will create for each such message an Action message where the original message (Goal, Feedback, Result) + action metadata is stored (goal id, status, etc.).
In order to work with ROS actions from jrosactionlib users need to:
To simplify this process users are encouraged to use msgmonster application.
In this example we are going to execute actions in Fibonacci action server using Java.
Before moving further we need to create and run Fibonacci action server based on the instructions from ROS documentation:
ROS action file Fibonacci.action looks something like this:
int32 order --- int32[] sequence --- int32[] partial_sequence
We need to map it to the corresponding jrosactionlib action definitions Java class. Use final results of these definitions for ROS2 or ROS1
Once Java action definition is created, it can be used to run ROS actions.
Once we have Fibonacci action definitions ready we can use them to execute actions on Fibonacci action server.
Required Java dependencies:
Code:
var clientFactory = new JRos2ClientFactory(); var actionlibFactory = new JRos2ActionFactory(); try (var client = clientFactory.createClient(); var actionlibClient = actionlibFactory.createClient( client, new FibonacciActionDefinition(), "fibonacci")) { var goal = new FibonacciGoalMessage().withOrder(13); var result = actionlibClient.sendGoalAsync(goal).get(); System.out.println(result); }
Required Java dependencies:
var clientFactory = new JRos1ClientFactory(); var actionClientFactory = new JRos1ActionClientFactory(); try (var client = clientFactory.createClient("http://127.0.0.1:11311/"); var actionClient = actionClientFactory .createClient(client, new FibonacciActionDefinition(), "fibonacci")) { var goal = new FibonacciGoalMessage().withOrder(new Int32Message().withData(5)); var result = actionClient.sendGoalAsync(goal).get(); System.out.println(result); }
In this example we are going to:
Code:
var clientFactory = new JRos2ClientFactory(); var actionlibFactory = new JRos2ActionFactory(); Function<Integer, int[]> fibo = order -> { var seq = new int[order]; seq[0] = 1; if (seq.length == 1) return seq; seq[1] = 1; if (seq.length == 2) return seq; for (int i = 2; i < seq.length; i++) { seq[i] = seq[i - 1] + seq[i - 2]; } return seq; }; ActionHandler<FibonacciGoalMessage, FibonacciResultMessage> handler = goal -> { System.out.println("Received new goal " + goal); var result = new FibonacciResultMessage(fibo.apply(goal.order)); System.out.println("Result " + result); return CompletableFuture.completedFuture(result); }; try (var client = clientFactory.createClient(); var actionServer = actionlibFactory.createActionServer( client, new FibonacciActionDefinition(), "jros_fibonacci", handler)) { actionServer.start(); System.out.println("Press Enter to stop ROS Action Server..."); System.in.read(); }
In terminal, use "ros2" command to send goals to "jros_fibonacci" Java action server:
Waiting for an action server to become available... Sending goal: order: 10 Goal accepted with ID: 226d976848e249ae8dfd106dfd81a1f6 Result: sequence: - 1 - 1 - 2 - 3 - 5 - 8 - 13 - 21 - 34 - 55 Goal finished with status: SUCCEEDED