Skip to content

Commit 647d869

Browse files
authored
Support Fast DDS basic RPC calls (#147)
* Support Fast DDS basic RPC calls Signed-off-by: Raul Sanchez-Mateos <raul@eprosima.com> * Uncrustify Signed-off-by: Raul Sanchez-Mateos <raul@eprosima.com> * Reduce redundant code and improve code reusability· Signed-off-by: Raul Sanchez-Mateos <raul@eprosima.com> * Uncrustify Signed-off-by: Raul Sanchez-Mateos <raul@eprosima.com> --------- Signed-off-by: Raul Sanchez-Mateos <raul@eprosima.com>
1 parent 2d4e84c commit 647d869

2 files changed

Lines changed: 176 additions & 66 deletions

File tree

ddspipe_core/include/ddspipe_core/types/topic/rpc/RpcTopic.hpp

Lines changed: 57 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -73,6 +73,26 @@ class RpcTopic
7373
static bool is_service_topic(
7474
const DdsTopic& topic);
7575

76+
//! Whether a topic is a ROS2 request topic
77+
DDSPIPE_CORE_DllAPI
78+
static bool is_ros2_request_topic(
79+
const DdsTopic& topic);
80+
81+
//! Whether a topic is a ROS2 reply topic
82+
DDSPIPE_CORE_DllAPI
83+
static bool is_ros2_reply_topic(
84+
const DdsTopic& topic);
85+
86+
//! Whether a topic is a FastDDS request topic
87+
DDSPIPE_CORE_DllAPI
88+
static bool is_fastdds_request_topic(
89+
const DdsTopic& topic);
90+
91+
//! Whether a topic is a FastDDS reply topic
92+
DDSPIPE_CORE_DllAPI
93+
static bool is_fastdds_reply_topic(
94+
const DdsTopic& topic);
95+
7696
/**
7797
* Minor operator
7898
*
@@ -83,6 +103,21 @@ class RpcTopic
83103

84104
protected:
85105

106+
static bool has_prefix(
107+
const std::string& str,
108+
const std::string& prefix)
109+
{
110+
return str.find(prefix) == 0;
111+
}
112+
113+
static bool has_suffix(
114+
const std::string& str,
115+
const std::string& suffix)
116+
{
117+
return str.size() >= suffix.size() &&
118+
str.compare(str.size() - suffix.size(), suffix.size(), suffix) == 0;
119+
}
120+
86121
//! Name of the service
87122
std::string service_name_;
88123

@@ -92,11 +127,28 @@ class RpcTopic
92127
//! Topic used for transmitting replies
93128
DdsTopic reply_topic_;
94129

95-
static const std::string REQUEST_PREFIX_STR;
96-
static const std::string REPLY_PREFIX_STR;
97-
static const std::string REQUEST_STR;
98-
static const std::string REPLY_STR;
99-
static const std::string RESPONSE_STR;
130+
//! Prefix used for request topic
131+
std::string request_prefix_;
132+
//! Suffix used for request topic
133+
std::string request_suffix_;
134+
//! Prefix used for reply topic
135+
std::string reply_prefix_;
136+
//! Suffix used for reply topic
137+
std::string reply_suffix_;
138+
139+
static const std::string ROS_TOPIC_REQUEST_PREFIX_STR;
140+
static const std::string ROS_TOPIC_REPLY_PREFIX_STR;
141+
static const std::string ROS_TOPIC_REQUEST_SUFFIX_STR;
142+
static const std::string ROS_TOPIC_REPLY_SUFFIX_STR;
143+
static const std::string ROS_TYPE_REQUEST_SUFFIX_STR;
144+
static const std::string ROS_TYPE_REPLY_SUFFIX_STR;
145+
146+
static const std::string FASTDDS_TOPIC_REQUEST_PREFIX_STR;
147+
static const std::string FASTDDS_TOPIC_REPLY_PREFIX_STR;
148+
static const std::string FASTDDS_TOPIC_REQUEST_SUFFIX_STR;
149+
static const std::string FASTDDS_TOPIC_REPLY_SUFFIX_STR;
150+
static const std::string FASTDDS_TYPE_REQUEST_SUFFIX_STR;
151+
static const std::string FASTDDS_TYPE_REPLY_SUFFIX_STR;
100152
};
101153

102154
/**

ddspipe_core/src/cpp/types/topic/rpc/RpcTopic.cpp

Lines changed: 119 additions & 61 deletions
Original file line numberDiff line numberDiff line change
@@ -29,11 +29,19 @@ namespace ddspipe {
2929
namespace core {
3030
namespace types {
3131

32-
const std::string RpcTopic::REQUEST_PREFIX_STR = "rq/";
33-
const std::string RpcTopic::REPLY_PREFIX_STR = "rr/";
34-
const std::string RpcTopic::REQUEST_STR = "Request";
35-
const std::string RpcTopic::REPLY_STR = "Reply";
36-
const std::string RpcTopic::RESPONSE_STR = "Response";
32+
const std::string RpcTopic::ROS_TOPIC_REQUEST_PREFIX_STR = "rq/";
33+
const std::string RpcTopic::ROS_TOPIC_REPLY_PREFIX_STR = "rr/";
34+
const std::string RpcTopic::ROS_TOPIC_REQUEST_SUFFIX_STR = "Request";
35+
const std::string RpcTopic::ROS_TOPIC_REPLY_SUFFIX_STR = "Reply";
36+
const std::string RpcTopic::ROS_TYPE_REQUEST_SUFFIX_STR = "Request_";
37+
const std::string RpcTopic::ROS_TYPE_REPLY_SUFFIX_STR = "Response_";
38+
39+
const std::string RpcTopic::FASTDDS_TOPIC_REQUEST_PREFIX_STR = "";
40+
const std::string RpcTopic::FASTDDS_TOPIC_REPLY_PREFIX_STR = "";
41+
const std::string RpcTopic::FASTDDS_TOPIC_REQUEST_SUFFIX_STR = "_Request";
42+
const std::string RpcTopic::FASTDDS_TOPIC_REPLY_SUFFIX_STR = "_Reply";
43+
const std::string RpcTopic::FASTDDS_TYPE_REQUEST_SUFFIX_STR = "_Request";
44+
const std::string RpcTopic::FASTDDS_TYPE_REPLY_SUFFIX_STR = "_Reply";
3745

3846
RpcTopic::RpcTopic(
3947
const std::string& service_name,
@@ -42,59 +50,80 @@ RpcTopic::RpcTopic(
4250
: service_name_(service_name)
4351
, request_topic_(request_topic)
4452
, reply_topic_(reply_topic)
53+
, request_prefix_("")
54+
, request_suffix_ ("")
55+
, reply_prefix_ ("")
56+
, reply_suffix_ ("")
4557
{
4658
}
4759

4860
RpcTopic::RpcTopic(
4961
const DdsTopic& topic) noexcept
5062
{
51-
if (is_request_topic(topic))
63+
if (is_service_topic(topic))
5264
{
53-
request_topic_ = topic;
54-
55-
reply_topic_ = topic;
56-
reply_topic_.m_topic_name =
57-
std::regex_replace(reply_topic_.m_topic_name, std::regex(REQUEST_PREFIX_STR), REPLY_PREFIX_STR);
58-
reply_topic_.m_topic_name =
59-
std::regex_replace(reply_topic_.m_topic_name, std::regex(REQUEST_STR), REPLY_STR);
60-
reply_topic_.type_name =
61-
std::regex_replace(reply_topic_.type_name, std::regex(REQUEST_STR), RESPONSE_STR);
62-
63-
service_name_ = std::regex_replace(topic.m_topic_name, std::regex(REQUEST_PREFIX_STR + "|" + REQUEST_STR), "");
64-
}
65-
else if (is_reply_topic(topic))
66-
{
67-
reply_topic_ = topic;
68-
69-
request_topic_ = topic;
70-
request_topic_.m_topic_name =
71-
std::regex_replace(request_topic_.m_topic_name, std::regex(REPLY_PREFIX_STR), REQUEST_PREFIX_STR);
72-
request_topic_.m_topic_name =
73-
std::regex_replace(request_topic_.m_topic_name, std::regex(REPLY_STR), REQUEST_STR);
74-
request_topic_.type_name =
75-
std::regex_replace(request_topic_.type_name, std::regex(RESPONSE_STR), REQUEST_STR);
76-
77-
service_name_ = std::regex_replace(topic.m_topic_name, std::regex(REPLY_PREFIX_STR + "|" + REPLY_STR), "");
65+
if (is_ros2_request_topic(topic) || is_ros2_reply_topic(topic))
66+
{
67+
request_prefix_ = RpcTopic::ROS_TOPIC_REQUEST_PREFIX_STR;
68+
request_suffix_ = RpcTopic::ROS_TOPIC_REQUEST_SUFFIX_STR;
69+
reply_prefix_ = RpcTopic::ROS_TOPIC_REPLY_PREFIX_STR;
70+
reply_suffix_ = RpcTopic::ROS_TOPIC_REPLY_SUFFIX_STR;
71+
}
72+
else if (is_fastdds_request_topic(topic) || is_fastdds_reply_topic(topic))
73+
{
74+
request_prefix_ = RpcTopic::FASTDDS_TOPIC_REQUEST_PREFIX_STR;
75+
request_suffix_ = RpcTopic::FASTDDS_TOPIC_REQUEST_SUFFIX_STR;
76+
reply_prefix_ = RpcTopic::FASTDDS_TOPIC_REPLY_PREFIX_STR;
77+
reply_suffix_ = RpcTopic::FASTDDS_TOPIC_REPLY_SUFFIX_STR;
78+
}
79+
80+
if (is_request_topic(topic))
81+
{
82+
request_topic_ = topic;
83+
reply_topic_ = topic;
84+
reply_topic_.m_topic_name =
85+
std::regex_replace(reply_topic_.m_topic_name, std::regex(request_prefix_), reply_prefix_);
86+
reply_topic_.m_topic_name =
87+
std::regex_replace(reply_topic_.m_topic_name, std::regex(request_suffix_), reply_suffix_);
88+
reply_topic_.type_name =
89+
std::regex_replace(reply_topic_.type_name, std::regex(request_suffix_), reply_suffix_);
90+
91+
service_name_ =
92+
std::regex_replace(topic.m_topic_name, std::regex(request_prefix_ + "|" + request_suffix_), "");
93+
}
94+
else
95+
{
96+
reply_topic_ = topic;
97+
request_topic_ = topic;
98+
request_topic_.m_topic_name =
99+
std::regex_replace(request_topic_.m_topic_name, std::regex(reply_prefix_), request_prefix_);
100+
request_topic_.m_topic_name =
101+
std::regex_replace(request_topic_.m_topic_name, std::regex(reply_suffix_), request_suffix_);
102+
request_topic_.type_name =
103+
std::regex_replace(request_topic_.type_name, std::regex(reply_suffix_), request_suffix_);
104+
105+
service_name_ =
106+
std::regex_replace(topic.m_topic_name, std::regex(reply_prefix_ + "|" + reply_suffix_), "");
107+
}
108+
109+
reply_topic_.m_internal_type_discriminator = INTERNAL_TOPIC_TYPE_RPC;
110+
request_topic_.m_internal_type_discriminator = INTERNAL_TOPIC_TYPE_RPC;
111+
112+
// Set both topic qos as the one found
113+
request_topic_.topic_qos = topic.topic_qos;
114+
reply_topic_.topic_qos = topic.topic_qos;
115+
116+
// WORKAROUND: Remove type information from RPC topics. Currently the creation of an RPC topic is triggered when
117+
// an entity corresponding to the request or reply topics is discovered. This way, the topic and type names of the
118+
// other topic conforming the pair is deduced. However it is not possible to deduce the type information, so we
119+
// leave this field empty until the creation mechanism is adapted to cover this scenario.
120+
request_topic_.type_identifiers = fastdds::dds::xtypes::TypeIdentifierPair();
121+
reply_topic_.type_identifiers = fastdds::dds::xtypes::TypeIdentifierPair();
78122
}
79123
else
80124
{
81-
utils::tsnh(
82-
utils::Formatter() << "Attempting to create RpcTopic from invalid topic.");
125+
utils::tsnh(utils::Formatter() << "Attempting to create RpcTopic from invalid topic.");
83126
}
84-
85-
reply_topic_.m_internal_type_discriminator = INTERNAL_TOPIC_TYPE_RPC;
86-
request_topic_.m_internal_type_discriminator = INTERNAL_TOPIC_TYPE_RPC;
87-
88-
// Set both topic qos as the one found
89-
request_topic_.topic_qos = topic.topic_qos;
90-
reply_topic_.topic_qos = topic.topic_qos;
91-
92-
// WORKAROUND: Remove type information from RPC topics. Currently the creation of an RPC topic is triggered when
93-
// an entity corresponding to the request or reply topics is discovered. This way, the topic and type names of the
94-
// other topic conforming the pair is deduced. However it is not possible to deduce the type information, so we
95-
// leave this field empty until the creation mechanism is adapted to cover this scenario.
96-
request_topic_.type_identifiers = fastdds::dds::xtypes::TypeIdentifierPair();
97-
reply_topic_.type_identifiers = fastdds::dds::xtypes::TypeIdentifierPair();
98127
}
99128

100129
RpcTopic::RpcTopic(
@@ -121,32 +150,61 @@ const DdsTopic& RpcTopic::reply_topic() const
121150
return reply_topic_;
122151
}
123152

124-
bool RpcTopic::is_request_topic(
153+
bool RpcTopic::is_ros2_request_topic(
125154
const DdsTopic& topic)
126155
{
127-
std::string m_topic_name = topic.m_topic_name;
128-
std::string type_name = topic.type_name;
156+
return has_prefix(topic.m_topic_name, RpcTopic::ROS_TOPIC_REQUEST_PREFIX_STR) &&
157+
has_suffix(topic.m_topic_name, RpcTopic::ROS_TOPIC_REQUEST_SUFFIX_STR) &&
158+
has_suffix(topic.type_name, RpcTopic::ROS_TYPE_REQUEST_SUFFIX_STR);
159+
}
129160

130-
return (m_topic_name.find(REQUEST_PREFIX_STR) == 0) &&
131-
(m_topic_name.rfind(REQUEST_STR) + REQUEST_STR.length() == m_topic_name.length()) &&
132-
(type_name.rfind(REQUEST_STR) + REQUEST_STR.length() + 1 == type_name.length());
161+
bool RpcTopic::is_ros2_reply_topic(
162+
const DdsTopic& topic)
163+
{
164+
return has_prefix(topic.m_topic_name, RpcTopic::ROS_TOPIC_REPLY_PREFIX_STR) &&
165+
has_suffix(topic.m_topic_name, RpcTopic::ROS_TOPIC_REPLY_SUFFIX_STR) &&
166+
has_suffix(topic.type_name, RpcTopic::ROS_TYPE_REPLY_SUFFIX_STR);
133167
}
134168

135-
bool RpcTopic::is_reply_topic(
169+
bool RpcTopic::is_fastdds_request_topic(
170+
const DdsTopic& topic)
171+
{
172+
return has_prefix(topic.m_topic_name, RpcTopic::FASTDDS_TOPIC_REQUEST_PREFIX_STR) &&
173+
has_suffix(topic.m_topic_name, RpcTopic::FASTDDS_TOPIC_REQUEST_SUFFIX_STR) &&
174+
has_suffix(topic.type_name, RpcTopic::FASTDDS_TYPE_REQUEST_SUFFIX_STR);
175+
}
176+
177+
bool RpcTopic::is_fastdds_reply_topic(
178+
const DdsTopic& topic)
179+
{
180+
return has_prefix(topic.m_topic_name, RpcTopic::FASTDDS_TOPIC_REPLY_PREFIX_STR) &&
181+
has_suffix(topic.m_topic_name, RpcTopic::FASTDDS_TOPIC_REPLY_SUFFIX_STR) &&
182+
has_suffix(topic.type_name, RpcTopic::FASTDDS_TYPE_REPLY_SUFFIX_STR);
183+
}
184+
185+
bool RpcTopic::is_request_topic(
136186
const DdsTopic& topic)
137187
{
138-
std::string m_topic_name = topic.m_topic_name;
139-
std::string type_name = topic.type_name;
188+
return is_ros2_request_topic(topic) || is_fastdds_request_topic(topic);
189+
}
140190

141-
return (m_topic_name.find(REPLY_PREFIX_STR) == 0) &&
142-
(m_topic_name.rfind(REPLY_STR) + REPLY_STR.length() == m_topic_name.length()) &&
143-
(type_name.rfind(RESPONSE_STR) + RESPONSE_STR.length() + 1 == type_name.length());
191+
bool RpcTopic::is_reply_topic(
192+
const DdsTopic& topic)
193+
{
194+
return is_ros2_reply_topic(topic) || is_fastdds_reply_topic(topic);
144195
}
145196

146-
bool RpcTopic::is_service_topic(
197+
bool RpcTopic::is_service_topic (
147198
const DdsTopic& topic)
148199
{
149-
return is_request_topic(topic) || is_reply_topic(topic);
200+
201+
if (is_ros2_request_topic(topic) || is_ros2_reply_topic(topic) ||
202+
is_fastdds_request_topic(topic) || is_fastdds_reply_topic(topic))
203+
{
204+
return true;
205+
}
206+
207+
return false;
150208
}
151209

152210
bool RpcTopic::operator <(

0 commit comments

Comments
 (0)