-
Notifications
You must be signed in to change notification settings - Fork 194
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
Start article defining actions #143
Conversation
Also apologies for the extra commits; my repository is a bit of a mess because #99 has not been merged and I unfortunately did that in the gh-pages branch. |
@gbiggs thanks for doing this! The "Serving and using actions" section talks about templated classes for the client and server - this seems like an implementation detail that will vary per language. Is the intent of this document to define the message level protocol, or to define the code level API (or both?). |
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 like a good start to me, but we'll have to fill in more technical details as the implementation starts.
One style note is that we prefer one sentence per line, so that line comments can be more specific and to minimize diffs, see: https://github.com/ros2/ros2/wiki/Developer-Guide#markdown
|
||
## Background | ||
|
||
ROS services, which provide synchronous Remote Procedure Calls, are a useful concept for sending a request and getting a rapid reply. But in robotics there are many instances where a reply may take a significant length of time. Additionally, there are occasions when it is useful to send a request to do some processing or perform some action in the world, where the result is less important than the effect of carrying it out. The progress of such requests often needs to be tracked, success or failure must be known in addition to receiving back information produced, and the request may need to be cancelled or altered before it completes. These requirements cannot be fulfilled by a simple RPC mechanism, whether or not it is asynchronous. |
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.
ROS 1 services were indeed only synchronous, but ROS 2 services can be asynchronous. It is true however that most of the time they are used for short synchronous requests.
"in addition to receiving feedback information"?
|
||
To satisfy these use cases, ROS provides a third communication paradigm known as "actions". An action is a goal-oriented request that occurs asynchronously to the requester, is typically (but not necessarily) longer-running than immediate, can be cancelled or replaced during execution, and has a server that provides feedback on execution progress. | ||
|
||
This document defines how actions are specified, what they look like to ROS users (both node developers and system integrators) |
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.
nitpick: punctuation
|
||
Actions are a first-class citizen in the ROS API, alongside topics and services. | ||
|
||
Action clients will use an API that provides a proxy object for the action. This will be a templated class, using the action class generated from the action specification as the template parameter. The client shall create an instance of this class, providing the address of the intended action server. Each instance of this class can only be related to one action server. Methods of the class will provide facilities for sending a goal to the action server, receiving a result, and getting 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.
In order to enforce the one action server per address, we would need to ensure this at the service level which we don't right now. This is tied to the node name uniqueness issue which we still haven't addressed yet.
We can set that as a goal, but when it comes time to implement we may just have to push this problem for the time being.
|
||
Action servers will use an API that provides a templated server class, using the action class generated from the action specification as the template parameter. The node implementer will create a function that implements the action's behaviour, create an instance of the templated server class, and bind the implementing function to the server. The implementing function will receive as one of its parameters the received goal message, and as another parameter the action server instance. The implementation shall use the action server instance to provide progress feedback and to report the result and success/failure/error status of the action's execution. | ||
|
||
Actions may be used from or served by real-time nodes. Therefore the actions API must be real-time capable. |
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.
This is a good goal, but we'll have to make some more qualifications on this most likely. We'd also have to make sure services are real-time, which I'm not sure they necessarily are at the moment.
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.
Not all use cases would necessarily need to be supported in realtime. If there's an asynchronous API such that the realtime thread can poll/pump the action client/server without blocking that could be made realtime safe. I'd suggest qualifying this assertion to suggest that there's at least one approach that's realtime safe.
Also, I agree with @jonbinney that the stuff about client and server API's is pretty C++ specific and a bit speculative at the moment. There's no problem with that per se, but the most important thing this document could capture is the behavior and some of the language agnostic implementation ideas. |
Thanks for the comments. I'm going to start rewriting the article. I might also make a new fork and pull request because my fork is a right mess and a pain to deal with... |
@gbiggs @wjwwood @tfoote - what's the status of this PR, is this still WIP? I'm interested in getting to the next level implementation details, such as what should the C++ API and Python API look like? I was thinking this would be a part of the rclcpp::Node interface, but per another conversation, I think there were plans to make this a separate library interface? |
Unfortunately I haven't done anything on this since my last comment. I have all the motivation and none of the time. I do want to get back to it, though. If you're interested, I can start a new pull request (as I mentioned previously, my fork is a mess and I need to nuke it and start over) and we can begin a conversation. One thing that was holding me up is on the implementation side. OSRF has put some thought into how actions should be implemented in DDS, but I'm not aware what they came up with. Knowing that would help, especially with building a prototype. |
@gbiggs - thanks for the reply. I've started looking into this also, because actions are needed for Navigation, which my team is working on now. If you have any more info, that's great, please add it. If not, I am hoping @wjwwood or another OSRF member will. If we have enough of the design and implementation details figured out, my team and I might be able to help with the implementation. |
|
||
In ROS 1, actions are visible in the output of the `rostopic` tool. | ||
|
||
In ROS 2, actions will not be visible as a set of topics. Nor will they be visible as a set of services [in the case that services be used to implement them]. They will be visible using a separate `ros2 action` command line tool. |
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.
@wjwwood @tfoote @gbiggs - is it possible to have a topic be 'hidden' or 'private' in some way that makes it invisible to the 'ros2 topic list' command? Similarly can a service be hidden? If so I was thinking the Action message interface is a combination of an 'hidden' asynchronous service and a 'hidden' topic. Is that possible?
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.
There is the notion of hidden topics and services. Topics/services starting with an underscore _
are considered "hidden".
Design doc reference: http://design.ros2.org/articles/topic_and_service_names.html#hidden-topic-or-service-names
The commandline tools will not show these topics by default but should provide a flag to display them.
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.
@mikaelarguedas - Thank you for the fast answer. So given that is the case, can Action servers be implemented as a class that internally creates both a hidden service and a hidden topic? Likewise an action client would call that service and subscribe to that topic.
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.
Yes I think this is doable 👍
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.
@mikaelarguedas - given that is true, there are at least 2 ways to implement this I can think of:
- Port actionlib and actionlib_msgs directly, except adding the "hiding" of topic and service names
- This would be the most straight 'port' possible
- Would still need to update the ros2utils to add the 'ros2 actions' functions. This is needed no matter what option is chosen
- don't know what colcon / ament build changes are needed if any
- Create new ActionServer and ActionClient classes for ROS2, with create_action_server and create_action_client as part of the node interface available in rclpy and rclcpp
- This would make Actions available through the node interface directly, just like Topics and Services
- They could be implemented internally as 'hidden' topics and services
- still need to add the 'ros2 actions' functions
- don't know what colcon / ament build changes are needed if any
Any other options? I think Actions could be plumbed down all the way to the RMW layer but I don't know how beneficial that would be, and it might result in unneeded code duplication of what is in Services and Topics today.
Please share your thoughts on this. My team is going to be blocked by this for Navigation, but if we can figure out the design, we could potentially help with some of the implementation work.
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.
I'm in favour of option 2, because I want to see actions be treated as first-class citizens like topics and services in ROS 2, not the ignored illegal alien that they are in ROS 1 tooling.
A simple implementation would be to just use hidden topics and services, and I see this as being the easiest way to go to prototype the API. Since the implementation and the high-level API/tooling design should be relatively independent, this could be a good way to get something useable out. However, I wouldn't want this to lead to stagnation that results in a better implementation that takes advantage of available rmw
/DDS features not being produced. I'm very keen to hear what the OSRF people had thought about how DDS would be leveraged for actions.
I've made a new pull request for this over here, because I needed to create a new fork to fix the messed up git history. |
This pull request is intended to start the discussion about how actions should be done in ROS 2. There are implementation aspects, which I think @mikaelarguedas expressed knowing something about over on Discourse. There are also user-facing aspects, such as where actions should be defined and what the API should look like. The current content is based on actionlib's implementation.