-
Notifications
You must be signed in to change notification settings - Fork 58
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
actions: add example action client and server
- Loading branch information
1 parent
6684a65
commit a4621c7
Showing
4 changed files
with
179 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,87 @@ | ||
using System; | ||
using System.Threading; | ||
using System.Threading.Tasks; | ||
using ROS2; | ||
using test_msgs.action; | ||
|
||
namespace ConsoleApplication | ||
{ | ||
public static class RCLDotnetService | ||
{ | ||
public static void Main(string[] args) | ||
{ | ||
RCLdotnet.Init(); | ||
var node = RCLdotnet.CreateNode("action_client"); | ||
|
||
var actionClient = node.CreateActionClient<Fibonacci, Fibonacci_Goal, Fibonacci_Result, Fibonacci_Feedback>("fibonacci"); | ||
|
||
var cts = new CancellationTokenSource(); | ||
var task = DoWorkAsync(actionClient, cts.Token); | ||
|
||
while (RCLdotnet.Ok()) | ||
{ | ||
RCLdotnet.SpinOnce(node, 500); | ||
|
||
if (task.IsCompletedSuccessfully) | ||
{ | ||
break; | ||
} | ||
else if (task.IsFaulted) | ||
{ | ||
Console.WriteLine($"Task faulted. Exception {task.Exception}"); | ||
break; | ||
} | ||
else if (task.IsCanceled) | ||
{ | ||
Console.WriteLine("Task canceled."); | ||
break; | ||
} | ||
} | ||
|
||
cts.Cancel(); | ||
task.GetAwaiter().GetResult(); | ||
} | ||
|
||
private static async Task DoWorkAsync( | ||
ActionClient<Fibonacci, Fibonacci_Goal, Fibonacci_Result, Fibonacci_Feedback> actionClient, | ||
CancellationToken cancellationToken) | ||
{ | ||
while (!actionClient.ServerIsReady()) | ||
{ | ||
cancellationToken.ThrowIfCancellationRequested(); | ||
|
||
// NOTE: This causes the code to resume in an background worker Thread. | ||
// Consider this when copying code from the example if additional synchronization is needed. | ||
await Task.Delay(1000, cancellationToken); | ||
} | ||
|
||
var goal = new Fibonacci_Goal(); | ||
goal.Order = 10; | ||
|
||
Console.WriteLine("SendGoal"); | ||
|
||
ActionClientGoalHandle<Fibonacci, Fibonacci_Goal, Fibonacci_Result, Fibonacci_Feedback> goalHandleForCallback = null; | ||
|
||
var goalHandle = await actionClient.SendGoalAsync(goal, (Fibonacci_Feedback feedback) => | ||
{ | ||
Console.WriteLine($"Feedback: {string.Join(", ", feedback.Sequence)}"); | ||
Console.WriteLine($"Status after Feedback: {goalHandleForCallback.Status}"); | ||
}); | ||
|
||
goalHandleForCallback = goalHandle; | ||
|
||
if (goalHandle.Accepted) | ||
{ | ||
Console.WriteLine("Goal accepted."); | ||
|
||
var result = await goalHandle.GetResultAsync(); | ||
Console.WriteLine($"Result: {string.Join(", ", result.Sequence)}"); | ||
Console.WriteLine($"Status: {goalHandle.Status}"); | ||
} | ||
else | ||
{ | ||
Console.WriteLine("Goal not accepted."); | ||
} | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,70 @@ | ||
using System; | ||
using System.Collections.Generic; | ||
using System.Threading; | ||
using System.Threading.Tasks; | ||
using ROS2; | ||
using test_msgs.action; | ||
|
||
namespace ConsoleApplication | ||
{ | ||
public static class RCLDotnetService | ||
{ | ||
public static void Main(string[] args) | ||
{ | ||
RCLdotnet.Init(); | ||
var node = RCLdotnet.CreateNode("action_server"); | ||
|
||
var actionServer = node.CreateActionServer<Fibonacci, Fibonacci_Goal, Fibonacci_Result, Fibonacci_Feedback>("fibonacci", HandleAccepted, cancelCallback: HandleCancel); | ||
|
||
RCLdotnet.Spin(node); | ||
} | ||
|
||
private static void HandleAccepted(ActionServerGoalHandle<Fibonacci, Fibonacci_Goal, Fibonacci_Result, Fibonacci_Feedback> goalHandle) | ||
{ | ||
// Don't block in the callback. | ||
// -> Don't wait for the returned Task. | ||
_ = DoWorkWithGoal(goalHandle); | ||
} | ||
|
||
private static CancelResponse HandleCancel(ActionServerGoalHandle<Fibonacci, Fibonacci_Goal, Fibonacci_Result, Fibonacci_Feedback> goalHandle) | ||
{ | ||
return CancelResponse.Accept; | ||
} | ||
|
||
private static async Task DoWorkWithGoal(ActionServerGoalHandle<Fibonacci, Fibonacci_Goal, Fibonacci_Result, Fibonacci_Feedback> goalHandle) | ||
{ | ||
Console.WriteLine("Executing goal..."); | ||
var feedback = new Fibonacci_Feedback(); | ||
|
||
feedback.Sequence = new List<int> { 0, 1 }; | ||
|
||
for (int i = 1; i < goalHandle.Goal.Order; i++) | ||
{ | ||
if (goalHandle.IsCanceling) | ||
{ | ||
var cancelResult = new Fibonacci_Result(); | ||
cancelResult.Sequence = feedback.Sequence; | ||
|
||
Console.WriteLine($"Canceled Result: {string.Join(", ", cancelResult.Sequence)}"); | ||
goalHandle.Canceled(cancelResult); | ||
return; | ||
} | ||
|
||
feedback.Sequence.Add(feedback.Sequence[i] + feedback.Sequence[i - 1]); | ||
|
||
Console.WriteLine($"Feedback: {string.Join(", ", feedback.Sequence)}"); | ||
goalHandle.PublishFeedback(feedback); | ||
|
||
// NOTE: This causes the code to resume in an background worker Thread. | ||
// Consider this when copying code from the example if additional synchronization is needed. | ||
await Task.Delay(1000); | ||
} | ||
|
||
var result = new Fibonacci_Result(); | ||
result.Sequence = feedback.Sequence; | ||
|
||
Console.WriteLine($"Result: {string.Join(", ", result.Sequence)}"); | ||
goalHandle.Succeed(result); | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters