Conversation
sloretz
left a comment
There was a problem hiding this comment.
Partial review (I looked at tests). I'll start reviewing the implementation next.
|
I still have to implement the synchronous methods (meant to do that prior to this PR). |
sloretz
left a comment
There was a problem hiding this comment.
Another partial review, this time for the C code. There are not as many comments as it seems, they're mostly repetitive.
With functions for creating and destroying action clients.
* Add boilerplate for send/take functions * Move common conversion function to shared header file (impl/convert.h) * Start implementing Waitable API * Add unit tests
Updated documentation and improved some error handling.
* Reset feedback member between each test * Used timed_spin() instead of spin_once()
* Better error handling * Move common typedef's to common.h * Return Python tuples from C functions instead of lists or custom Python object * Bugfix: pass Capsule objects for QoS profiles when creating an action client
523c403 to
b661737
Compare
| from unique_identifier_msgs.msg import UUID | ||
|
|
||
|
|
||
| class ClientGoalHandle(): |
There was a problem hiding this comment.
The C++ equivalent has a method to get a future for the goal result. Possible to implement that here?
| for seq, req_future in pending_requests.items(): | ||
| if future == req_future: | ||
| try: | ||
| del pending_requests[seq] |
There was a problem hiding this comment.
Is anything testing this? I would be surprised if it works since items() is a generator in python 3. See this SO post. Maybe it needs a request after the one being deleted to to see an error?
There was a problem hiding this comment.
No explicit tests, but I tried a test sending multiple goals concurrently and still works. It would raise an exception, but the iteration stops on the first deletion because of the return statement below. Anyways, it's probably safer to cast the items to a list as suggested in the SO post.
We might consider doing the same for the service client code as well:
Lines 70 to 76 in 0fafaec
rclpy/rclpy/action_client.py
Outdated
|
|
||
| return future | ||
|
|
||
| def get_result(self, goal_handle): |
There was a problem hiding this comment.
I would expect this method to only be on the goal_handle, like is done in rclcpp_action
rclpy/rclpy/action_client.py
Outdated
|
|
||
| return future | ||
|
|
||
| def cancel_goal(self, goal_handle): |
There was a problem hiding this comment.
I would expect this to be a method on the goal handle.
There was a problem hiding this comment.
In rclcpp_action this is done via the action client:
But, I do agree that it is more intuitive to move this to the goal handle. Since the implementation is closely tied to the ActionClient, what do you think about leaving these here as hidden methods and providing a facade in GoalHandle?
Also, after looking at rclcpp, I realized I'm missing functions for "cancel all goals" and "cancel goals before".
Signed-off-by: Jacob Perron <jacob@openrobotics.org>
Signed-off-by: Jacob Perron <jacob@openrobotics.org>
Signed-off-by: Jacob Perron <jacob@openrobotics.org>
Signed-off-by: Jacob Perron <jacob@openrobotics.org>
Signed-off-by: Jacob Perron <jacob@openrobotics.org>
Now it acts as the users interface for canceling goals and getting goal results. Remove the unit tests specific to ClientGoalHandle since it is now closely coupled with the ActionClient and is sufficiently covered in the ActionClient unit tests. Signed-off-by: Jacob Perron <jacob@openrobotics.org>
|
@sloretz I've addressed all of your comments. I've hidden the Perhaps if we add the notion of a client goal handle to |
Signed-off-by: Jacob Perron <jacob@openrobotics.org>
Signed-off-by: Jacob Perron <jacob@openrobotics.org>
Increased to 400 seconds. Signed-off-by: Jacob Perron <jacob@openrobotics.org>
This reverts commit b6c6ca8.
Signed-off-by: Jacob Perron <jacob@openrobotics.org>
|
I'm not sure why, but the multi-threaded test was timing out on CI machines. I've disabled it and opened an issue (#268) to come back to. |
* Add rclpy_action module With functions for creating and destroying action clients. * Implement action client * Move common conversion function and typedefs to shared header file (impl/common.h) * Add tests using mock action server * Add action module for aggregating action related submodules * Extend Waitable API so executors are aware of Futures * Move check_for_type_support() to its own module Signed-off-by: Jacob Perron <jacob@openrobotics.org>
* Add Action Client (#262) * Add rclpy_action module With functions for creating and destroying action clients. * Implement action client * Move common conversion function and typedefs to shared header file (impl/common.h) * Add tests using mock action server * Add action module for aggregating action related submodules * Extend Waitable API so executors are aware of Futures * Move check_for_type_support() to its own module Signed-off-by: Jacob Perron <jacob@openrobotics.org> * Fix Executor not executing tasks if there are no ready entities in the wait set (#272) If a task is created, then trigger the Executors guard condition. This will wake any blocking call to `rcl_wait()`. In this scenario, no work is yielded, so we also have to move the check for 'in-progress' tasks into the wait loop. Added a unit test to reproduce the issue. This resolves an issue in some cases where the result response from the action server is never processed, therefore never reaching the action client. Signed-off-by: Jacob Perron <jacob@openrobotics.org> * Fix Node's reference to executor (#275) Previously, if a `Node` was added to an `Executor` using the executors `add_node` method, then nodes `executor` property would return `None`. Signed-off-by: Jacob Perron <jacob@openrobotics.org> * Abstract type conversions into functions (#269) * Abstract type conversions into functions This helps with readability and maintainability. Also eliminated use of assertions during conversions, defering to exceptions. * Move common C functions to a shared library 'rclpy_common' Signed-off-by: Jacob Perron <jacob@openrobotics.org> * Add ActionServer (#270) * Add Action server functions to extension module * Separated service related macros into separate request and response calls * Add server goal handle functions to extension module * Update Action extension module to use conversion functions * Add implementation of Python ActionServer * Handles goal and cancel requests, responds, and calls user-defined functions for executing goals. * Handle result requests * Handle expired goals * Publish goal status array and feedback * Add `handle_accepted_callback` to ActionServer Upon accepting a goal, the provided `handle_accepted_callback` is called with a reference to the goal handle. The user can then decide to execute the goal or defer. If `handle_accepted_callback` is not provided, then the default behavior is to execute the goal handle immediately. Signed-off-by: Jacob Perron <jacob@openrobotics.org> * Enable test using MultiThreadedExecutor (#280) Signed-off-by: Jacob Perron <jacob@openrobotics.org> * Guard against failed take when taking action messages (#281) Some middlewares (e.g. Connext and OpenSplice) send invalid messages to indicate an instance has been disposed which results in a 'failed take'. Signed-off-by: Jacob Perron <jacob@openrobotics.org>
Connects to #257
_rclpy_actionextension module for interfacingrcl_actionlibrary andrclpyI still need to go through and update the code documentation and perhaps add some more unit tests.