-
Notifications
You must be signed in to change notification settings - Fork 5
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #37 from felixdivo/support-calling-actions
Support testing actions
- Loading branch information
Showing
8 changed files
with
299 additions
and
5 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
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
5 changes: 5 additions & 0 deletions
5
ros2_easy_test/tests/example_launch_files/fibonacci_action.yaml
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,5 @@ | ||
launch: | ||
- executable: | ||
name: Talker | ||
cmd: python ros2_easy_test/tests/example_nodes/run_node.py ros2_easy_test/tests/example_nodes/minimal_action_server.py MinimalActionServer | ||
output: screen |
93 changes: 93 additions & 0 deletions
93
ros2_easy_test/tests/example_nodes/minimal_action_server.py
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,93 @@ | ||
# Modified from original example in examples_rclpy_minimal_action_server.server as follows: | ||
# 1. pass *args, **kwargs to __init__ and super().__init__. | ||
# 2. Reduce sleep times. | ||
# | ||
# Copyright 2019 Open Source Robotics Foundation, Inc. | ||
# | ||
# Licensed under the Apache License, Version 2.0 (the "License"); | ||
# you may not use this file except in compliance with the License. | ||
# You may obtain a copy of the License at | ||
# | ||
# http://www.apache.org/licenses/LICENSE-2.0 | ||
# | ||
# Unless required by applicable law or agreed to in writing, software | ||
# distributed under the License is distributed on an "AS IS" BASIS, | ||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
# See the License for the specific language governing permissions and | ||
# limitations under the License. | ||
|
||
import time | ||
|
||
from example_interfaces.action import Fibonacci | ||
from rclpy.action import ActionServer, CancelResponse, GoalResponse | ||
from rclpy.callback_groups import ReentrantCallbackGroup | ||
from rclpy.node import Node | ||
|
||
|
||
class MinimalActionServer(Node): | ||
def __init__(self, *args, **kwargs): | ||
super().__init__("minimal_action_server", *args, **kwargs) | ||
|
||
self._action_server = ActionServer( | ||
self, | ||
Fibonacci, | ||
"fibonacci", | ||
execute_callback=self.execute_callback, | ||
callback_group=ReentrantCallbackGroup(), | ||
goal_callback=self.goal_callback, | ||
cancel_callback=self.cancel_callback, | ||
) | ||
|
||
def destroy(self): | ||
self._action_server.destroy() | ||
super().destroy_node() | ||
|
||
def goal_callback(self, goal_request): | ||
"""Accept or reject a client request to begin an action.""" | ||
# This server allows multiple goals in parallel | ||
self.get_logger().info("Received goal request") | ||
return GoalResponse.ACCEPT | ||
|
||
def cancel_callback(self, goal_handle): | ||
"""Accept or reject a client request to cancel an action.""" | ||
self.get_logger().info("Received cancel request") | ||
return CancelResponse.ACCEPT | ||
|
||
async def execute_callback(self, goal_handle): | ||
"""Execute a goal.""" | ||
self.get_logger().info("Executing goal...") | ||
|
||
# Append the seeds for the Fibonacci sequence | ||
feedback_msg = Fibonacci.Feedback() | ||
feedback_msg.sequence = [0, 1] | ||
|
||
# Helps avoid race condition in testing. | ||
time.sleep(0.1) | ||
|
||
# Start executing the action | ||
for i in range(1, goal_handle.request.order): | ||
if goal_handle.is_cancel_requested: | ||
goal_handle.canceled() | ||
self.get_logger().info("Goal canceled") | ||
return Fibonacci.Result() | ||
|
||
# Update Fibonacci sequence | ||
feedback_msg.sequence.append(feedback_msg.sequence[i] + feedback_msg.sequence[i - 1]) | ||
|
||
self.get_logger().info(f"Publishing feedback: {feedback_msg.sequence}") | ||
|
||
# Publish the feedback | ||
goal_handle.publish_feedback(feedback_msg) | ||
|
||
# Sleep for demonstration purposes | ||
time.sleep(0.01) | ||
|
||
goal_handle.succeed() | ||
|
||
# Populate result message | ||
result = Fibonacci.Result() | ||
result.sequence = feedback_msg.sequence | ||
|
||
self.get_logger().info(f"Returning result: {result.sequence}") | ||
|
||
return 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
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,47 @@ | ||
"""Tests that actions can be checked correctly.""" | ||
|
||
# ROS2 infrastructure | ||
from example_interfaces.action import Fibonacci | ||
|
||
# What we are testing | ||
from ros2_easy_test import ROS2TestEnvironment, with_launch_file, with_single_node | ||
|
||
# Module under test and interfaces | ||
from . import LAUNCH_FILES | ||
from .example_nodes.minimal_action_server import MinimalActionServer | ||
|
||
|
||
@with_single_node(MinimalActionServer) | ||
def test_fibonacci_action_direct(env: ROS2TestEnvironment) -> None: | ||
"""Test calling an action.""" | ||
|
||
feedbacks, result = env.send_action_goal_and_wait_for_result( | ||
name="fibonacci", goal=Fibonacci.Goal(order=4) | ||
) | ||
|
||
assert len(feedbacks) == 3 | ||
assert feedbacks == [ | ||
Fibonacci.Feedback(sequence=[0, 1, 1]), | ||
Fibonacci.Feedback(sequence=[0, 1, 1, 2]), | ||
Fibonacci.Feedback(sequence=[0, 1, 1, 2, 3]), | ||
] | ||
|
||
assert result.result == Fibonacci.Result(sequence=[0, 1, 1, 2, 3]) | ||
|
||
|
||
@with_launch_file(LAUNCH_FILES / "fibonacci_action.yaml") | ||
def test_fibonacci_action_launch_file(env: ROS2TestEnvironment) -> None: | ||
"""Test calling an action.""" | ||
|
||
feedbacks, result = env.send_action_goal_and_wait_for_result( | ||
name="fibonacci", goal=Fibonacci.Goal(order=4) | ||
) | ||
|
||
assert len(feedbacks) == 3 | ||
assert feedbacks == [ | ||
Fibonacci.Feedback(sequence=[0, 1, 1]), | ||
Fibonacci.Feedback(sequence=[0, 1, 1, 2]), | ||
Fibonacci.Feedback(sequence=[0, 1, 1, 2, 3]), | ||
] | ||
|
||
assert result.result == Fibonacci.Result(sequence=[0, 1, 1, 2, 3]) |