Open arshPratap opened 1 year ago
@pablogs9 any idea how to proceed with this ?
@Acuadros95 any updates on this ? I would really like to know how to proceed with this issue
Hello @arshPratap have you considered taking a look at micro-ROS RWM, there we are using XRCE to create ROS 2 interoperable services. Probably following the same approach, you will be able to use ROS 2 services directly from XRCE: https://github.com/micro-ROS/rmw_microxrcedds/blob/bc4eb312ac4601a4137c35f4a56b9b83b4b18339/rmw_microxrcedds_c/src/rmw_service.c#L30
Thanks for the response @pablogs9 I am currently going through the code .. if possible could this implementation be further strecthed to use ros2-actions ?
Here's how we solved this for the DDS client implementation used in ArduPilot's AP_DDS
library, using the ArmMotors
service definition as an example:
ROS 2 service definition: ardupilot_msgs/srv/ArmMotors.srv
# This service requests the vehicle to arm or disarm its motors.
# Set true to arm motors, false to disarm motors.
bool arm
---
# True if arming/disarming request for motors was successful , false otherwise.
bool result
IDL:
// generated from rosidl_adapter/resource/srv.idl.em
// with input from ardupilot_msgs/srv/ArmMotors.srv
// generated code does not contain a copyright notice
module ardupilot_msgs {
module srv {
struct ArmMotors_Request {
@verbatim (language="comment", text=
"This service requests the vehicle to arm or disarm its motors." "\n"
"Set true to arm motors, false to disarm motors.")
boolean arm;
};
@verbatim (language="comment", text=
"True if arming/disarming request for motors was successful , false otherwise. ")
struct ArmMotors_Response {
boolean result;
};
};
};
The micro XRCE DDS client creates the service Replier using uxr_buffer_create_replier_ref
, and the key to auto mapping the DDS messages to ROS 2 is using the following naming in the refs file:
<?xml version="1.0"?>
<profiles>
<participant profile_name="participant_profile">
<rtps>
<name>ardupilot_dds</name>
</rtps>
</participant>
...
<replier
profile_name="arm_motors__replier"
service_name="rs/ap/arm_motorsService"
request_type="ardupilot_msgs::srv::dds_::ArmMotors_Request_"
reply_type="ardupilot_msgs::srv::dds_::ArmMotors_Response_">
<request_topic_name>rq/ap/arm_motorsRequest</request_topic_name>
<reply_topic_name>rr/ap/arm_motorsReply</reply_topic_name>
</replier>
</profiles>
with this choice the ArmMotors
service may be called from the ROS 2 CLI without the need to run an Integration Service instance:
$ ros2 service call /ap/arm_motors ardupilot_msgs/srv/ArmMotors "{arm: True}"
requester: making request: ardupilot_msgs.srv.ArmMotors_Request(arm=True)
response:
ardupilot_msgs.srv.ArmMotors_Response(result=True)
Yup can confirm that the approach works.. Thanks a lot for the help @srmainwaring
Here's how we solved this for the DDS client implementation used in ArduPilot's
AP_DDS
library, using theArmMotors
service definition as an example:ROS 2 service definition:
ardupilot_msgs/srv/ArmMotors.srv
# This service requests the vehicle to arm or disarm its motors. # Set true to arm motors, false to disarm motors. bool arm --- # True if arming/disarming request for motors was successful , false otherwise. bool result
IDL:
// generated from rosidl_adapter/resource/srv.idl.em // with input from ardupilot_msgs/srv/ArmMotors.srv // generated code does not contain a copyright notice module ardupilot_msgs { module srv { struct ArmMotors_Request { @verbatim (language="comment", text= "This service requests the vehicle to arm or disarm its motors." "\n" "Set true to arm motors, false to disarm motors.") boolean arm; }; @verbatim (language="comment", text= "True if arming/disarming request for motors was successful , false otherwise. ") struct ArmMotors_Response { boolean result; }; }; };
The micro XRCE DDS client creates the service Replier using
uxr_buffer_create_replier_ref
, and the key to auto mapping the DDS messages to ROS 2 is using the following naming in the refs file:<?xml version="1.0"?> <profiles> <participant profile_name="participant_profile"> <rtps> <name>ardupilot_dds</name> </rtps> </participant> ... <replier profile_name="arm_motors__replier" service_name="rs/ap/arm_motorsService" request_type="ardupilot_msgs::srv::dds_::ArmMotors_Request_" reply_type="ardupilot_msgs::srv::dds_::ArmMotors_Response_"> <request_topic_name>rq/ap/arm_motorsRequest</request_topic_name> <reply_topic_name>rr/ap/arm_motorsReply</reply_topic_name> </replier> </profiles>
with this choice the
ArmMotors
service may be called from the ROS 2 CLI without the need to run an Integration Service instance:$ ros2 service call /ap/arm_motors ardupilot_msgs/srv/ArmMotors "{arm: True}" requester: making request: ardupilot_msgs.srv.ArmMotors_Request(arm=True) response: ardupilot_msgs.srv.ArmMotors_Response(result=True)
Yup can confirm that the approach works.. Thanks a lot for the help @srmainwaring
Currently I am trying to recreate the ReplyAdder example to communicate with ROS-2 nodes and was fairly successful in doing so with the ROS-2 nodes via integration services. My current question is that is there a way to directly communicate with ROS-2 nodes using the micro-ros agent (similar to how it was tackled in #250 ). Based on the docs , my current replier configuration is as follows :
But on the ROS-2 side there is no corresponding service listed when I run :
ros2 service list
Any ideas how to proceed with this ? Thanks