domain_bridge
domain_bridge copied to clipboard
Support actions
Similar to topics and services, it would be nice to also support ROS actions.
Since actions are built upon topics and services, the bridge implementation will depend on how we decide to bridge services (https://github.com/ros2/domain_bridge/issues/10).
Hello, is there any possibility to do so at the moment? I'm already building a custom executable to add my specific services (#10 and #54), but it seems like there are no equivalent functions for actions...
The short answer is "no", the bridge does not currently support bridging actions.
I haven't thought too much about how we would support Actions, but I imagine we could do something similar as we did for services: create a custom executable that depends on the action types you want to bridge. I guess this would involve adding a template method bridge_action<T>, like we did in #26 for services. However, think it becomes a bit more complex with actions since they involve bridging a combination of topics and services.
Hello, I have tried the brigde to pass actions between two domains (no problem with topics), specifically the fibonacci example in the documentation, but I can't get it to work. I followed the design document Actions are still not supported?
Regards,
Hey, commenting for future reference after seeing your comment. It's possible to bridge actions using the underlying services/topics used by rclcpp_action.
One note, these hidden services can also be called in command line, and for me for debug it was quite useful :)
The commands ros2 service --include-hidden-services list -t and ros2 topic --include-hidden-topic list -t are quite useful to know what your hidden services/topics are
For example I have this action on endpoint /action_log_download of type custom::action::Log and bridging it with these lines:
- in the YAML configuration:
/action_log_download/_action/feedback:
type: custom/action/Log_FeedbackMessage
/action_log_download/_action/status:
type: action_msgs/msg/GoalStatusArray
- in the
src/domain_bridge.cpp
#include "custom/action/log.hpp"
#include "action_msgs/srv/cancel_goal.hpp"
[...]
std::cout << timestamp() << "Bridging services for log action" << std::endl;
domain_bridge.bridge_service<custom::action::Log_SendGoal>("/action_log_download/_action/send_goal", 1, 0);
domain_bridge.bridge_service<action_msgs::srv::CancelGoal>("/action_log_download/_action/cancel_goal", 1, 0);
domain_bridge.bridge_service<custom::action::Log_GetResult>("/action_log_download/_action/get_result", 1, 0);
For me it works flawlessly, so no real need to add something to bridge actions.
Hi @Vicidel . Thank you for your input. I have tried but it doesn't work for me.
I'm running the action_tutorials_cpp fibonacci_action_server in ROS_Domain 2.
- This is the list of services running (with the parameter "--include-hidden-services" is the same list )
ros2@ros2-VirtualBox:~$ ros2 service list -t
/fibonacci_action_server/describe_parameters [rcl_interfaces/srv/DescribeParameters]
/fibonacci_action_server/get_parameter_types [rcl_interfaces/srv/GetParameterTypes]
/fibonacci_action_server/get_parameters [rcl_interfaces/srv/GetParameters]
/fibonacci_action_server/list_parameters [rcl_interfaces/srv/ListParameters]
/fibonacci_action_server/set_parameters [rcl_interfaces/srv/SetParameters]
/fibonacci_action_server/set_parameters_atomically [rcl_interfaces/srv/SetParametersAtomically]
- The list of topic(no hidden topics) :
ros2@ros2-VirtualBox:~$ ros2 topic list -t
/parameter_events [rcl_interfaces/msg/ParameterEvent]
/rosout [rcl_interfaces/msg/Log]
ros2@ros2-VirtualBox:~$ ros2 topic --include-hidden-topic list -t
/parameter_events [rcl_interfaces/msg/ParameterEvent]
/rosout [rcl_interfaces/msg/Log]
- I modified domain_bridge.cpp in this way (The bridge will runs in domain 2 (the action client also) and the action server runs in 3 ):
#include "action_tutorials_interfaces/action/fibonacci.hpp"
#include "rcl_interfaces/srv/describe_parameters.hpp"
#include "rcl_interfaces/srv/get_parameter_types.hpp"
#include "rcl_interfaces/srv/get_parameters.hpp"
#include "rcl_interfaces/srv/list_parameters.hpp"
#include "rcl_interfaces/srv/set_parameters.hpp"
#include "rcl_interfaces/srv/set_parameters_atomically.hpp"
[...]
auto end = std::chrono::system_clock::now();
std::time_t end_time = std::chrono::system_clock::to_time_t(end);
std::cout << std::ctime(&end_time) << "Bridging services for log action CUSTOM" << std::endl;
domain_bridge.bridge_service<rcl_interfaces::srv::DescribeParameters>("/fibonacci_action_server/describe_parameters", 2, 3);
domain_bridge.bridge_service<rcl_interfaces::srv::GetParameterTypes>("/fibonacci_action_server/get_parameter_types", 2, 3);
domain_bridge.bridge_service<rcl_interfaces::srv::GetParameters>("/fibonacci_action_server/get_parameters", 2, 3);
domain_bridge.bridge_service<rcl_interfaces::srv::ListParameters>("/fibonacci_action_server/list_parameters", 2, 3);
domain_bridge.bridge_service<rcl_interfaces::srv::SetParameters>("/fibonacci_action_server/set_parameters", 2, 3);
domain_bridge.bridge_service<rcl_interfaces::srv::SetParameters>("/fibonacci_action_server/set_parameters_atomically", 2, 3);
- The bridge configuration in the yaml.
name: my_bridge
from_domain: 2
to_domain: 3
topics:
chatter:
type: std_msgs/msg/String
services:
/fibonacci_action_server/describe_parameters:
type: rcl_interfaces/srv/DescribeParameters
/fibonacci_action_server/get_parameter_types:
type: rcl_interfaces/srv/GetParameterTypes
/fibonacci_action_server/get_parameters:
type: rcl_interfaces/srv/GetParameters
/fibonacci_action_server/list_parameters:
type: rcl_interfaces/srv/ListParameters
/fibonacci_action_server/set_parameters:
type: rcl_interfaces/srv/SetParameters
/fibonacci_action_server/set_parameters_atomically:
type: rcl_interfaces/srv/SetParameters
- Finally
- I start the fibonnaci action server in Domain 3. (
ros2 run action_tutorials_cpp fibonacci_action_server) - I start the ros2 bridge customized in domain 2.
- I call the action server from Domain 2 (
ros2 action send_goal fibonacci /action/Fibonacci "{order: 5}")
I'm sure I'm doing something wrong, I have very little know about C++.
Thanks in advance.