ROS 2 ardent
以下srv 檔案使用ROS 2 提供現成的,屬於package example_interfaces
先建立一個srv 檔案
描述request 為int a 及int b
reply 則為int sum
AddTwoInts.srv
int64 aint64 b---int64 sum |
ROS 2 會先轉成2個msg 檔案,如下
AddTwoInts_Request.msg
int64 aint64 b |
AddTwoInts_Response.msg
int64 sum |
ROS 2 再從這兩個msg 檔案產生總共4 個idl
以下會以Request 為例 (Reply 是一樣的)
AddTwoInts_Request_.idl
// generated from rosidl_generator_dds_idl/resource/msg.idl.em#ifndef __example_interfaces__srv__AddTwoInts_Request__idl__#define __example_interfaces__srv__AddTwoInts_Request__idl__module example_interfaces{module srv{module dds_{struct AddTwoInts_Request_{ long long a_; long long b_;}; // struct AddTwoInts_Request_#pragma keylist AddTwoInts_Request_}; // module dds_}; // module srv}; // module example_interfaces#endif // __example_interfaces__srv__AddTwoInts_Request__idl__ |
Sample_AddTwoInts_Request_.idl
// generated from rosidl_generator_dds_idl/resource/msg.idl.em#ifndef __example_interfaces__srv__Sample_AddTwoInts_Request__idl__#define __example_interfaces__srv__Sample_AddTwoInts_Request__idl__#include "example_interfaces/srv/dds_opensplice/AddTwoInts_Request_.idl"module example_interfaces{module srv{module dds_{struct Sample_AddTwoInts_Request_{ unsigned long long client_guid_0_; unsigned long long client_guid_1_; long long sequence_number_; example_interfaces::srv::dds_::AddTwoInts_Request_ request_;}; // struct Sample_AddTwoInts_Request_#pragma keylist Sample_AddTwoInts_Request_}; // module dds_}; // module srv}; // module example_interfaces#endif // __example_interfaces__srv__Sample_AddTwoInts_Request__idl__ |
使用VortexOpenSplice 或者VortexLite 的generator 這4個idl 轉成要用的DDS 語言 header
idl 內的include 路徑須自行修改
例如用VortexOpenSplice 建立c99 的header 會得到以下檔案
接著coding 必須引入這些檔案
假如我們要做為一個server 端,接收request 及發送reply
其source code 簡單如下
#include "Sample_AddTwoInts_Request_.h"#include "Sample_AddTwoInts_Response_.h"int main(int argc, char **argv){ int error = dds_init(argc, argv); if (error < 0) { printf("dds_init %d\n", dds_err_no(error)); } dds_entity_t pp; dds_qos_t *pp_qos = dds_qos_create(); dds_qset_userdata(pp_qos, "name=service_dds;", 18); //ROS 2 node name error = dds_participant_create(&pp, DDS_DOMAIN_DEFAULT, pp_qos, NULL); if (error < 0) { printf("dds_participant_create %d\n", dds_err_no(error)); } /* create topics addTwoIntsRequest and addTwoIntsReply so ros2 can use service list to check addTwoInts partiton rq for addTwoIntsRequest partiton rr for addTwoIntsReply should be reliable too */ /*=======================================================*/ dds_entity_t topic; error = dds_topic_create(pp, &topic, &example_interfaces_srv_dds__Sample_AddTwoInts_Request__desc, "addTwoIntsRequest", NULL, NULL); if (error < 0) { printf("dds_topic_create %d\n", dds_err_no(error)); } dds_qos_t *qos = dds_qos_create(); const char * partitions[1]; partitions[0] = "rq"; dds_qset_reliability(qos, DDS_RELIABILITY_RELIABLE, DDS_SECS(1)); dds_qset_durability(qos, DDS_DURABILITY_TRANSIENT_LOCAL); dds_qset_partition(qos, 1, partitions); dds_entity_t sub; error = dds_subscriber_create(pp, &sub, qos, NULL); if (error < 0) { printf("dds_subscriber_create %d\n", dds_err_no(error)); } dds_entity_t reader; error = dds_reader_create(sub, &reader, topic, NULL, NULL); if (error < 0) { printf("dds_reader_create %d\n", dds_err_no(error)); } /*=======================================================*/ error = dds_topic_create(pp, &topic, &example_interfaces_srv_dds__Sample_AddTwoInts_Response__desc, "addTwoIntsReply", NULL, NULL); if (error < 0) { printf("dds_topic_create %d\n", dds_err_no(error)); } partitions[0] = "rr"; dds_qset_reliability(qos, DDS_RELIABILITY_RELIABLE, DDS_SECS(1)); dds_qset_durability(qos, DDS_DURABILITY_TRANSIENT_LOCAL); dds_qset_partition(qos, 1, partitions); dds_entity_t pub; error = dds_publisher_create(pp, &pub, qos, NULL); if (error < 0) { printf("dds_publisher_create %d\n", dds_err_no(error)); } dds_entity_t writer; error = dds_writer_create(pub, &writer, topic, NULL, NULL); if (error < 0) { printf("dds_writer_create %d\n", dds_err_no(error)); } /*=======================================================*/ dds_sample_info_t info = { 0 }; void *samples[1] = { {0} }; example_interfaces_srv_dds__Sample_AddTwoInts_Request_ *sample = NULL; example_interfaces_srv_dds__Sample_AddTwoInts_Response_ msg = { 0 }; while (1) { int ret = dds_take(reader, samples, 1, &info, DDS_ANY_STATE); if (ret > 0 && info.valid_data) { sample = samples[0]; int a = sample->request_.a_; int b = sample->request_.b_; int sum = a + b; printf("%d + %d = %d\n", a, b, sum); msg.client_guid_0_ = sample->client_guid_0_; msg.client_guid_1_ = sample->client_guid_1_; msg.response_.sum_ = sum; dds_sleepfor(DDS_SECS(1)); dds_write(writer, &msg); } dds_sleepfor(DDS_SECS(1)); }} |
編譯成功後並執行
於ROS 2 環境 可以得到以下結果
karlkwchen@karlkwchen-VirtualBox:~$ ros2 node listservice_ddskarlkwchen@karlkwchen-VirtualBox:~$ ros2 service list/addTwoIntskarlkwchen@karlkwchen-VirtualBox:~$ ros2 service call /addTwoInts example_interfaces/AddTwoInts "{a: 1, b: 3}"requester: making request: example_interfaces.srv.AddTwoInts_Request(a=1, b=3)response:example_interfaces.srv.AddTwoInts_Response(sum=4) |

沒有留言:
張貼留言