-
Notifications
You must be signed in to change notification settings - Fork 5
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add capability for testing actions. #27
Conversation
Actions can be tested with a single call like: goal_handle, feedbacks, result_response = env.send_action_goal_and_wait_for_response( name="fibonacci", action_type=Fibonacci, goal_msg=Fibonacci.Goal(order=4), ) See test_actions.py for details.
@felixdivo PTAL. |
Hey @vik748, I know I owe you a few comments, also regarding mock testing. Sorry for taking so long. I'll probably respond by the end of the week. I really value your efforts, and at first glance, it looked great. I'll have to find a few more minutes to go through it more slowly, though, hopefully this weekend. :) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks great so far!
Regarding the many Any
s: I think this cannot be avoided since ROS does not model special types for actions. For documentation, you could add an alias similar to RosMessage = Any
.
Regarding the automatic detection of action type. We always get a goal, e.g. This might works if you pass in # Get the type of the service
# This is a bit tricky but relieves the user from passing it explicitly
module = import_module(goal_class.__module__)
# We cut away the trailing "_Goal" from the type name, which has length 5
base_type_name = goal_class.__name__[:-5]
base_type_class: Type = getattr(module, base_type_name) |
Great work so far! |
@vik748 I am sorry for my slow responses. I will make sure to answer at least on a weekly basis from May one! |
|
||
def feedback_callback(self, feedback_msg: Any): | ||
"""Callback for action feedback messages.""" | ||
print(f"{feedback_msg.feedback=}") |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Feedback can happen a lot! So this print might become very verbose.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
print(f"{feedback_msg.feedback=}") |
For the record, this is how I do this kind of stuff now. It's an implementation without sleeps, so perhaps can serve as inspiration: from action_msgs.srv import CancelGoal
from my_package.action import MyAction
def test():
client = ActionClient(node, MyAction, "my_action")
assert client.wait_for_server(10.0), "No actionclient for my_action found"
event = threading.Event()
def unblock(future):
nonlocal event
event.set()
send_goal_future = self.send_goal_async(goal, **kwargs)
send_goal_future.add_done_callback(unblock)
event.wait()
goal_handle = send_goal_future.result()
assert goal_handle.accepted
print("Canceling action")
response: CancelGoal.Response = goal_handle.cancel_goal()
assert response.return_code == CancelGoal.Response.ERROR_NONE, "Canceling action failed" |
You could even pass a timeout to it. |
I'll react to PRs etc. more regularly from now on. |
Hey @vik748, after finally completing #33 and many minor cleanups, I was able to have a closer look at this. I was inspired by the ROS source code and @Timple's very similar suggestions. Since I did not want to bother you with more requests, I implemented the changes myself in #37. Thank you for the great work here and your patience. :) |
Per discussion in #25 this PR adds the capability to test actions with a single call like:
I couldn't figure out how to improve typing hints, so have a bunch of
Any
types.Also I couldn't figure out how to auto-infer action type similar to _get_service_client, could use help with that.