Limited time and resources…
For now action_bridge
is a proof-of-concept to test the implemented logic without the need for factories, code generation and auto-discovery. Integrating the functionality into ros1_bridge
should be the ultimate goal:
opened 12:14AM - 18 Oct 18 UTC
help wanted
In ros2/design#193 there is no description of how actions would be transmitted a… cross the ROS 1 bridge. This section should be written and included in the design document.
Some content was written, but then deleted after feedback found a lot of issues.
<details><summary>Deleted content for `Bridging between ROS 1 and ROS 2`</summary>
```markdown
## Bridging between ROS 1 and ROS 2
### Detecting Action Servers and Clients
There will be an API for the bridge to get a list of all ROS 2 action servers and clients.
ROS 1 action servers and clients can be discovered by looking for topic ending in `/status` with message type `actionlib_msgs/GoalStatusArray`.
If a publisher exists then an action server exists.
If a subscriber exists then a client exists.
### Bridging ROS 1 Action Client and ROS 2 Action Server
If either a ROS 2 action server or a ROS 1 action client exists then the ROS 1 bridge will create the following:
1. a ROS 1 action server
2. a ROS 2 action client
#### Goal submission
When the ROS 1 action client submits a goal the bridge will check if a ROS 2 action server exists.
If no server exists then the goal is rejected, otherwise the bridge calls the ROS 2 goal submission service.
If the ROS 2 server accepts the goal then the bridge will call `setAccepted` on the ROS 1 bridge, otherwise it will call `setRejected`.
When a goal is accepted the bridge stores a map between the ROS 1 and ROS 2 goal IDs.
If a client submits a goal with the same ID then it will be rejected until the first goal is finished.
#### Goal Cancellation
When a ROS 1 client tries to cancel a goal the bridge must try to cancel it on the ROS 2 server.
First the bridge must look up the mapping of ROS 1 to ROS 2 goal IDs.
If a mapping exists then the bridge will call the cancellation service.
If the mapping does not exist because the server has not yet accepted or rejected the goal then the bridge will wait until the goal is accepted.
If it is rejected the bridge will call setRejected and ignore the cancellation request.
If it is accepted then it will call the cancellation service.
#### Feedback
The bridge will only publish feedback messages for goals that were sent through it.
Since the goal ID is generated by the server, the bridge can only know the mapping of ROS 1 to ROS 2 goal IDs if the bridge sent the goal.
#### Result
Once a goal has been accepted the bridge will wait for the result.
When it gets the result the bridge will call
If the bridge notices the ROS 2 action server disappears from the node graph then bridge will wait for the result indefinitely.
When the bridge reappears the bridge will try to get the result from the goal again.
If the ROS 2 server does not know of the goal, then the bridge will notify the ROS 1 client that the goal was canceled.
### Bridging ROS 1 Action Server and ROS 2 Action Client
If either a ROS 1 action server or a ROS 2 action client exist then the bridge will create:
1. a ROS 1 action client
2. a ROS 2 action server
#### Goal submission
When the ROS 2 action client submits a goal the bridge will check if a ROS 1 action server exists.
If it does not exist the bridge will reject the goal, otherwise it will submit the goal to the ROS 1 server.
The same goal ID is to be used for both ROS 1 and ROS 2.
Goals sent to the bridge from ROS 2 are always immediately accepted by the bridge.
The bridge will then submit the goal to the ROS 1 server.
The reason for instantly accepting the goal is that if the ROS 1 action server never responds to a goal request then the bridge cannot return a result.
Goals that are rejected by ROS 1 action servers will be reported as canceled to ROS 2 action clients.
#### Goal Cancellation
When a ROS 2 client tries to cancel a goal the bridge will immediately accept the cancellation request.
It will then try to cancel the request on the ROS 1 action server.
If the cancellation request is rejected by the ROS 1 server then the ROS 2 bridge will stay in the *CANCELING* state until the result of the goal is known.
#### Feedback
Since the goal ID is the same for both ROS 1 and ROS 2, the bridge will always publish feedback from ROS 1 servers to the ROS 2 feedback topic.
#### Result
When the ROS 1 action server publishes a result it will be set as the result on the ROS 1 bridge.
If the ROS 2 action client never calls the service to get the result then it is subject to the same timeout as if it were a normal ROS 2 action server.
```
</details>
<br>
One issue is it has the bridge always accepting goals from ROS 2 action clients before contacting the ROS 1 action server, but that hides what's happening on the ROS 1 action server from ROS 2 introspection tools. Another issue is it "detects" a ROS 1 action server or client using only a single topic, but servers or clients aren't actually functional until all topics are in use. Yet another issue is it always creates an action server if there is an action client on one side, which makes it seem like there is an action server available when there isn't.
<br><br>
Since the section was written goal ids where changed back to being generated by the client, so there may not be a reason to prevent feedback from ROS 2 goals being transmitted to ROS 2.
Bridging actions is a little bit more complicated.
It involves conversion between topics and services, and translating the ROS1 and ROS2 action goal IDs. We are depending on actionlib
and rclcpp_action
to ensure the correct behavior, but this approach requires a thread for each goal to wait for the result.
A callback API for rclcpp_action
was introduced for dashing, it will simplify the integration and avoid these waiting threads.
1 Like