Skip to content

Commit b8f7237

Browse files
authored
add mechanism to pass rmw impl specific payloads during pub/sub creation (#882)
* add mechanism to pass rmw impl specific payloads during pub/sub creation Signed-off-by: William Woodall <[email protected]> * use class instead of struct Signed-off-by: William Woodall <[email protected]> * narrow API of rmw payload to just use rmw_*_options_t's Signed-off-by: William Woodall <[email protected]> * fixup after recent change Signed-off-by: William Woodall <[email protected]>
1 parent 27a97e8 commit b8f7237

11 files changed

+300
-2
lines changed

rclcpp/CMakeLists.txt

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,9 @@ set(${PROJECT_NAME}_SRCS
3232
src/rclcpp/clock.cpp
3333
src/rclcpp/context.cpp
3434
src/rclcpp/contexts/default_context.cpp
35+
src/rclcpp/detail/rmw_implementation_specific_payload.cpp
36+
src/rclcpp/detail/rmw_implementation_specific_publisher_payload.cpp
37+
src/rclcpp/detail/rmw_implementation_specific_subscription_payload.cpp
3538
src/rclcpp/duration.cpp
3639
src/rclcpp/event.cpp
3740
src/rclcpp/exceptions.cpp
Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
// Copyright 2019 Open Source Robotics Foundation, Inc.
2+
//
3+
// Licensed under the Apache License, Version 2.0 (the "License");
4+
// you may not use this file except in compliance with the License.
5+
// You may obtain a copy of the License at
6+
//
7+
// http://www.apache.org/licenses/LICENSE-2.0
8+
//
9+
// Unless required by applicable law or agreed to in writing, software
10+
// distributed under the License is distributed on an "AS IS" BASIS,
11+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
// See the License for the specific language governing permissions and
13+
// limitations under the License.
14+
15+
#ifndef RCLCPP__DETAIL__RMW_IMPLEMENTATION_SPECIFIC_PAYLOAD_HPP_
16+
#define RCLCPP__DETAIL__RMW_IMPLEMENTATION_SPECIFIC_PAYLOAD_HPP_
17+
18+
#include "rclcpp/visibility_control.hpp"
19+
20+
namespace rclcpp
21+
{
22+
namespace detail
23+
{
24+
25+
/// Mechanism for passing rmw implementation specific settings through the ROS interfaces.
26+
class RCLCPP_PUBLIC RMWImplementationSpecificPayload
27+
{
28+
public:
29+
virtual
30+
~RMWImplementationSpecificPayload() = default;
31+
32+
/// Return false if this class has not been customized, otherwise true.
33+
/**
34+
* It does this based on the value of the rmw implementation identifier that
35+
* this class reports, and so it is important for a specialization of this
36+
* class to override the get_rmw_implementation_identifier() method to return
37+
* something other than nullptr.
38+
*/
39+
bool
40+
has_been_customized() const;
41+
42+
/// Derrived classes should override this and return the identifier of its rmw implementation.
43+
virtual
44+
const char *
45+
get_implementation_identifier() const;
46+
};
47+
48+
} // namespace detail
49+
} // namespace rclcpp
50+
51+
#endif // RCLCPP__DETAIL__RMW_IMPLEMENTATION_SPECIFIC_PAYLOAD_HPP_
Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
// Copyright 2019 Open Source Robotics Foundation, Inc.
2+
//
3+
// Licensed under the Apache License, Version 2.0 (the "License");
4+
// you may not use this file except in compliance with the License.
5+
// You may obtain a copy of the License at
6+
//
7+
// http://www.apache.org/licenses/LICENSE-2.0
8+
//
9+
// Unless required by applicable law or agreed to in writing, software
10+
// distributed under the License is distributed on an "AS IS" BASIS,
11+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
// See the License for the specific language governing permissions and
13+
// limitations under the License.
14+
15+
#ifndef RCLCPP__DETAIL__RMW_IMPLEMENTATION_SPECIFIC_PUBLISHER_PAYLOAD_HPP_
16+
#define RCLCPP__DETAIL__RMW_IMPLEMENTATION_SPECIFIC_PUBLISHER_PAYLOAD_HPP_
17+
18+
#include "rcl/publisher.h"
19+
20+
#include "rclcpp/detail/rmw_implementation_specific_payload.hpp"
21+
#include "rclcpp/visibility_control.hpp"
22+
23+
namespace rclcpp
24+
{
25+
namespace detail
26+
{
27+
28+
class RCLCPP_PUBLIC RMWImplementationSpecificPublisherPayload
29+
: public RMWImplementationSpecificPayload
30+
{
31+
public:
32+
~RMWImplementationSpecificPublisherPayload() override = default;
33+
34+
/// Opportunity for a derived class to inject information into the rcl options.
35+
/**
36+
* This is called after the rcl_publisher_options_t has been prepared by
37+
* rclcpp, but before rcl_publisher_init() is called.
38+
*
39+
* The passed option is the rmw_publisher_options field of the
40+
* rcl_publisher_options_t that will be passed to rcl_publisher_init().
41+
*
42+
* By default the options are unmodified.
43+
*/
44+
virtual
45+
void
46+
modify_rmw_publisher_options(rmw_publisher_options_t & rmw_publisher_options) const;
47+
};
48+
49+
} // namespace detail
50+
} // namespace rclcpp
51+
52+
#endif // RCLCPP__DETAIL__RMW_IMPLEMENTATION_SPECIFIC_PUBLISHER_PAYLOAD_HPP_
Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
// Copyright 2019 Open Source Robotics Foundation, Inc.
2+
//
3+
// Licensed under the Apache License, Version 2.0 (the "License");
4+
// you may not use this file except in compliance with the License.
5+
// You may obtain a copy of the License at
6+
//
7+
// http://www.apache.org/licenses/LICENSE-2.0
8+
//
9+
// Unless required by applicable law or agreed to in writing, software
10+
// distributed under the License is distributed on an "AS IS" BASIS,
11+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
// See the License for the specific language governing permissions and
13+
// limitations under the License.
14+
15+
#ifndef RCLCPP__DETAIL__RMW_IMPLEMENTATION_SPECIFIC_SUBSCRIPTION_PAYLOAD_HPP_
16+
#define RCLCPP__DETAIL__RMW_IMPLEMENTATION_SPECIFIC_SUBSCRIPTION_PAYLOAD_HPP_
17+
18+
#include "rcl/subscription.h"
19+
20+
#include "rclcpp/detail/rmw_implementation_specific_payload.hpp"
21+
#include "rclcpp/visibility_control.hpp"
22+
23+
namespace rclcpp
24+
{
25+
namespace detail
26+
{
27+
28+
/// Subscription payload that may be rmw implementation specific.
29+
class RCLCPP_PUBLIC RMWImplementationSpecificSubscriptionPayload
30+
: public RMWImplementationSpecificPayload
31+
{
32+
public:
33+
~RMWImplementationSpecificSubscriptionPayload() override = default;
34+
35+
/// Opportunity for a derived class to inject information into the rcl options.
36+
/**
37+
* This is called after the rcl_subscription_options_t has been prepared by
38+
* rclcpp, but before rcl_subscription_init() is called.
39+
*
40+
* The passed option is the rmw_subscription_options field of the
41+
* rcl_subscription_options_t that will be passed to rcl_subscription_init().
42+
*
43+
* By default the options are unmodified.
44+
*/
45+
virtual
46+
void
47+
modify_rmw_subscription_options(rmw_subscription_options_t & rmw_subscription_options) const;
48+
};
49+
50+
} // namespace detail
51+
} // namespace rclcpp
52+
53+
#endif // RCLCPP__DETAIL__RMW_IMPLEMENTATION_SPECIFIC_SUBSCRIPTION_PAYLOAD_HPP_

rclcpp/include/rclcpp/publisher.hpp

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -288,6 +288,11 @@ class Publisher : public PublisherBase
288288
return message_seq;
289289
}
290290

291+
/// Copy of original options passed during construction.
292+
/**
293+
* It is important to save a copy of this so that the rmw payload which it
294+
* may contain is kept alive for the duration of the publisher.
295+
*/
291296
const rclcpp::PublisherOptionsWithAllocator<AllocatorT> options_;
292297

293298
std::shared_ptr<MessageAllocator> message_allocator_;

rclcpp/include/rclcpp/publisher_options.hpp

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222
#include "rcl/publisher.h"
2323

2424
#include "rclcpp/allocator/allocator_common.hpp"
25+
#include "rclcpp/detail/rmw_implementation_specific_publisher_payload.hpp"
2526
#include "rclcpp/intra_process_setting.hpp"
2627
#include "rclcpp/qos.hpp"
2728
#include "rclcpp/qos_event.hpp"
@@ -45,6 +46,10 @@ struct PublisherOptionsBase
4546

4647
/// Callback group in which the waitable items from the publisher should be placed.
4748
std::shared_ptr<rclcpp::callback_group::CallbackGroup> callback_group;
49+
50+
/// Optional RMW implementation specific payload to be used during creation of the publisher.
51+
std::shared_ptr<rclcpp::detail::RMWImplementationSpecificPublisherPayload>
52+
rmw_implementation_payload = nullptr;
4853
};
4954

5055
/// Structure containing optional configuration for Publishers.
@@ -72,9 +77,16 @@ struct PublisherOptionsWithAllocator : public PublisherOptionsBase
7277
auto message_alloc = std::make_shared<MessageAllocatorT>(*this->get_allocator().get());
7378
result.allocator = rclcpp::allocator::get_rcl_allocator<MessageT>(*message_alloc);
7479
result.qos = qos.get_rmw_qos_profile();
80+
81+
// Apply payload to rcl_publisher_options if necessary.
82+
if (rmw_implementation_payload && rmw_implementation_payload->has_been_customized()) {
83+
rmw_implementation_payload->modify_rmw_publisher_options(result.rmw_publisher_options);
84+
}
85+
7586
return result;
7687
}
7788

89+
7890
/// Get the allocator, creating one if needed.
7991
std::shared_ptr<Allocator>
8092
get_allocator() const

rclcpp/include/rclcpp/subscription.hpp

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -104,6 +104,7 @@ class Subscription : public SubscriptionBase
104104
options.template to_rcl_subscription_options<CallbackMessageT>(qos),
105105
rclcpp::subscription_traits::is_serialized_subscription_argument<CallbackMessageT>::value),
106106
any_callback_(callback),
107+
options_(options),
107108
message_memory_strategy_(message_memory_strategy)
108109
{
109110
if (options.event_callbacks.deadline_callback) {
@@ -302,6 +303,12 @@ class Subscription : public SubscriptionBase
302303
RCLCPP_DISABLE_COPY(Subscription)
303304

304305
AnySubscriptionCallback<CallbackMessageT, AllocatorT> any_callback_;
306+
/// Copy of original options passed during construction.
307+
/**
308+
* It is important to save a copy of this so that the rmw payload which it
309+
* may contain is kept alive for the duration of the subscription.
310+
*/
311+
const rclcpp::SubscriptionOptionsWithAllocator<AllocatorT> options_;
305312
typename message_memory_strategy::MessageMemoryStrategy<CallbackMessageT, AllocatorT>::SharedPtr
306313
message_memory_strategy_;
307314
};

rclcpp/include/rclcpp/subscription_options.hpp

Lines changed: 16 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020
#include <vector>
2121

2222
#include "rclcpp/callback_group.hpp"
23+
#include "rclcpp/detail/rmw_implementation_specific_subscription_payload.hpp"
2324
#include "rclcpp/intra_process_setting.hpp"
2425
#include "rclcpp/qos.hpp"
2526
#include "rclcpp/qos_event.hpp"
@@ -33,12 +34,19 @@ struct SubscriptionOptionsBase
3334
{
3435
/// Callbacks for events related to this subscription.
3536
SubscriptionEventCallbacks event_callbacks;
37+
3638
/// True to ignore local publications.
3739
bool ignore_local_publications = false;
40+
3841
/// The callback group for this subscription. NULL to use the default callback group.
3942
rclcpp::callback_group::CallbackGroup::SharedPtr callback_group = nullptr;
43+
4044
/// Setting to explicitly set intraprocess communications.
4145
IntraProcessSetting use_intra_process_comm = IntraProcessSetting::NodeDefault;
46+
47+
/// Optional RMW implementation specific payload to be used during creation of the subscription.
48+
std::shared_ptr<rclcpp::detail::RMWImplementationSpecificSubscriptionPayload>
49+
rmw_implementation_payload = nullptr;
4250
};
4351

4452
/// Structure containing optional configuration for Subscriptions.
@@ -61,13 +69,19 @@ struct SubscriptionOptionsWithAllocator : public SubscriptionOptionsBase
6169
rcl_subscription_options_t
6270
to_rcl_subscription_options(const rclcpp::QoS & qos) const
6371
{
64-
rcl_subscription_options_t result;
72+
rcl_subscription_options_t result = rcl_subscription_get_default_options();
6573
using AllocatorTraits = std::allocator_traits<Allocator>;
6674
using MessageAllocatorT = typename AllocatorTraits::template rebind_alloc<MessageT>;
6775
auto message_alloc = std::make_shared<MessageAllocatorT>(*allocator.get());
6876
result.allocator = allocator::get_rcl_allocator<MessageT>(*message_alloc);
69-
result.ignore_local_publications = this->ignore_local_publications;
7077
result.qos = qos.get_rmw_qos_profile();
78+
result.rmw_subscription_options.ignore_local_publications = this->ignore_local_publications;
79+
80+
// Apply payload to rcl_subscription_options if necessary.
81+
if (rmw_implementation_payload && rmw_implementation_payload->has_been_customized()) {
82+
rmw_implementation_payload->modify_rmw_subscription_options(result.rmw_subscription_options);
83+
}
84+
7185
return result;
7286
}
7387

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
// Copyright 2019 Open Source Robotics Foundation, Inc.
2+
//
3+
// Licensed under the Apache License, Version 2.0 (the "License");
4+
// you may not use this file except in compliance with the License.
5+
// You may obtain a copy of the License at
6+
//
7+
// http://www.apache.org/licenses/LICENSE-2.0
8+
//
9+
// Unless required by applicable law or agreed to in writing, software
10+
// distributed under the License is distributed on an "AS IS" BASIS,
11+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
// See the License for the specific language governing permissions and
13+
// limitations under the License.
14+
15+
#include <rclcpp/detail/rmw_implementation_specific_payload.hpp>
16+
17+
namespace rclcpp
18+
{
19+
namespace detail
20+
{
21+
22+
bool
23+
RMWImplementationSpecificPayload::has_been_customized() const
24+
{
25+
return nullptr != this->get_implementation_identifier();
26+
}
27+
28+
const char *
29+
RMWImplementationSpecificPayload::get_implementation_identifier() const
30+
{
31+
return nullptr;
32+
}
33+
34+
} // namespace detail
35+
} // namespace rclcpp
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
// Copyright 2019 Open Source Robotics Foundation, Inc.
2+
//
3+
// Licensed under the Apache License, Version 2.0 (the "License");
4+
// you may not use this file except in compliance with the License.
5+
// You may obtain a copy of the License at
6+
//
7+
// http://www.apache.org/licenses/LICENSE-2.0
8+
//
9+
// Unless required by applicable law or agreed to in writing, software
10+
// distributed under the License is distributed on an "AS IS" BASIS,
11+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
// See the License for the specific language governing permissions and
13+
// limitations under the License.
14+
15+
#include <rclcpp/detail/rmw_implementation_specific_publisher_payload.hpp>
16+
17+
#include "rcl/publisher.h"
18+
19+
namespace rclcpp
20+
{
21+
namespace detail
22+
{
23+
24+
void
25+
RMWImplementationSpecificPublisherPayload::modify_rmw_publisher_options(
26+
rmw_publisher_options_t & rmw_publisher_options) const
27+
{
28+
// By default, do not mutate the rmw publisher options.
29+
(void)rmw_publisher_options;
30+
}
31+
32+
} // namespace detail
33+
} // namespace rclcpp

0 commit comments

Comments
 (0)