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 <william@osrfoundation.org>

* use class instead of struct

Signed-off-by: William Woodall <william@osrfoundation.org>

* narrow API of rmw payload to just use rmw_*_options_t's

Signed-off-by: William Woodall <william@osrfoundation.org>

* fixup after recent change

Signed-off-by: William Woodall <william@osrfoundation.org>
This commit is contained in:
William Woodall 2019-10-08 15:40:27 -07:00 committed by GitHub
parent 27a97e868c
commit b8f7237087
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
11 changed files with 300 additions and 2 deletions

View file

@ -32,6 +32,9 @@ set(${PROJECT_NAME}_SRCS
src/rclcpp/clock.cpp src/rclcpp/clock.cpp
src/rclcpp/context.cpp src/rclcpp/context.cpp
src/rclcpp/contexts/default_context.cpp src/rclcpp/contexts/default_context.cpp
src/rclcpp/detail/rmw_implementation_specific_payload.cpp
src/rclcpp/detail/rmw_implementation_specific_publisher_payload.cpp
src/rclcpp/detail/rmw_implementation_specific_subscription_payload.cpp
src/rclcpp/duration.cpp src/rclcpp/duration.cpp
src/rclcpp/event.cpp src/rclcpp/event.cpp
src/rclcpp/exceptions.cpp src/rclcpp/exceptions.cpp

View file

@ -0,0 +1,51 @@
// Copyright 2019 Open Source Robotics Foundation, Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#ifndef RCLCPP__DETAIL__RMW_IMPLEMENTATION_SPECIFIC_PAYLOAD_HPP_
#define RCLCPP__DETAIL__RMW_IMPLEMENTATION_SPECIFIC_PAYLOAD_HPP_
#include "rclcpp/visibility_control.hpp"
namespace rclcpp
{
namespace detail
{
/// Mechanism for passing rmw implementation specific settings through the ROS interfaces.
class RCLCPP_PUBLIC RMWImplementationSpecificPayload
{
public:
virtual
~RMWImplementationSpecificPayload() = default;
/// Return false if this class has not been customized, otherwise true.
/**
* It does this based on the value of the rmw implementation identifier that
* this class reports, and so it is important for a specialization of this
* class to override the get_rmw_implementation_identifier() method to return
* something other than nullptr.
*/
bool
has_been_customized() const;
/// Derrived classes should override this and return the identifier of its rmw implementation.
virtual
const char *
get_implementation_identifier() const;
};
} // namespace detail
} // namespace rclcpp
#endif // RCLCPP__DETAIL__RMW_IMPLEMENTATION_SPECIFIC_PAYLOAD_HPP_

View file

@ -0,0 +1,52 @@
// Copyright 2019 Open Source Robotics Foundation, Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#ifndef RCLCPP__DETAIL__RMW_IMPLEMENTATION_SPECIFIC_PUBLISHER_PAYLOAD_HPP_
#define RCLCPP__DETAIL__RMW_IMPLEMENTATION_SPECIFIC_PUBLISHER_PAYLOAD_HPP_
#include "rcl/publisher.h"
#include "rclcpp/detail/rmw_implementation_specific_payload.hpp"
#include "rclcpp/visibility_control.hpp"
namespace rclcpp
{
namespace detail
{
class RCLCPP_PUBLIC RMWImplementationSpecificPublisherPayload
: public RMWImplementationSpecificPayload
{
public:
~RMWImplementationSpecificPublisherPayload() override = default;
/// Opportunity for a derived class to inject information into the rcl options.
/**
* This is called after the rcl_publisher_options_t has been prepared by
* rclcpp, but before rcl_publisher_init() is called.
*
* The passed option is the rmw_publisher_options field of the
* rcl_publisher_options_t that will be passed to rcl_publisher_init().
*
* By default the options are unmodified.
*/
virtual
void
modify_rmw_publisher_options(rmw_publisher_options_t & rmw_publisher_options) const;
};
} // namespace detail
} // namespace rclcpp
#endif // RCLCPP__DETAIL__RMW_IMPLEMENTATION_SPECIFIC_PUBLISHER_PAYLOAD_HPP_

View file

@ -0,0 +1,53 @@
// Copyright 2019 Open Source Robotics Foundation, Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#ifndef RCLCPP__DETAIL__RMW_IMPLEMENTATION_SPECIFIC_SUBSCRIPTION_PAYLOAD_HPP_
#define RCLCPP__DETAIL__RMW_IMPLEMENTATION_SPECIFIC_SUBSCRIPTION_PAYLOAD_HPP_
#include "rcl/subscription.h"
#include "rclcpp/detail/rmw_implementation_specific_payload.hpp"
#include "rclcpp/visibility_control.hpp"
namespace rclcpp
{
namespace detail
{
/// Subscription payload that may be rmw implementation specific.
class RCLCPP_PUBLIC RMWImplementationSpecificSubscriptionPayload
: public RMWImplementationSpecificPayload
{
public:
~RMWImplementationSpecificSubscriptionPayload() override = default;
/// Opportunity for a derived class to inject information into the rcl options.
/**
* This is called after the rcl_subscription_options_t has been prepared by
* rclcpp, but before rcl_subscription_init() is called.
*
* The passed option is the rmw_subscription_options field of the
* rcl_subscription_options_t that will be passed to rcl_subscription_init().
*
* By default the options are unmodified.
*/
virtual
void
modify_rmw_subscription_options(rmw_subscription_options_t & rmw_subscription_options) const;
};
} // namespace detail
} // namespace rclcpp
#endif // RCLCPP__DETAIL__RMW_IMPLEMENTATION_SPECIFIC_SUBSCRIPTION_PAYLOAD_HPP_

View file

@ -288,6 +288,11 @@ protected:
return message_seq; return message_seq;
} }
/// Copy of original options passed during construction.
/**
* It is important to save a copy of this so that the rmw payload which it
* may contain is kept alive for the duration of the publisher.
*/
const rclcpp::PublisherOptionsWithAllocator<AllocatorT> options_; const rclcpp::PublisherOptionsWithAllocator<AllocatorT> options_;
std::shared_ptr<MessageAllocator> message_allocator_; std::shared_ptr<MessageAllocator> message_allocator_;

View file

@ -22,6 +22,7 @@
#include "rcl/publisher.h" #include "rcl/publisher.h"
#include "rclcpp/allocator/allocator_common.hpp" #include "rclcpp/allocator/allocator_common.hpp"
#include "rclcpp/detail/rmw_implementation_specific_publisher_payload.hpp"
#include "rclcpp/intra_process_setting.hpp" #include "rclcpp/intra_process_setting.hpp"
#include "rclcpp/qos.hpp" #include "rclcpp/qos.hpp"
#include "rclcpp/qos_event.hpp" #include "rclcpp/qos_event.hpp"
@ -45,6 +46,10 @@ struct PublisherOptionsBase
/// Callback group in which the waitable items from the publisher should be placed. /// Callback group in which the waitable items from the publisher should be placed.
std::shared_ptr<rclcpp::callback_group::CallbackGroup> callback_group; std::shared_ptr<rclcpp::callback_group::CallbackGroup> callback_group;
/// Optional RMW implementation specific payload to be used during creation of the publisher.
std::shared_ptr<rclcpp::detail::RMWImplementationSpecificPublisherPayload>
rmw_implementation_payload = nullptr;
}; };
/// Structure containing optional configuration for Publishers. /// Structure containing optional configuration for Publishers.
@ -72,9 +77,16 @@ struct PublisherOptionsWithAllocator : public PublisherOptionsBase
auto message_alloc = std::make_shared<MessageAllocatorT>(*this->get_allocator().get()); auto message_alloc = std::make_shared<MessageAllocatorT>(*this->get_allocator().get());
result.allocator = rclcpp::allocator::get_rcl_allocator<MessageT>(*message_alloc); result.allocator = rclcpp::allocator::get_rcl_allocator<MessageT>(*message_alloc);
result.qos = qos.get_rmw_qos_profile(); result.qos = qos.get_rmw_qos_profile();
// Apply payload to rcl_publisher_options if necessary.
if (rmw_implementation_payload && rmw_implementation_payload->has_been_customized()) {
rmw_implementation_payload->modify_rmw_publisher_options(result.rmw_publisher_options);
}
return result; return result;
} }
/// Get the allocator, creating one if needed. /// Get the allocator, creating one if needed.
std::shared_ptr<Allocator> std::shared_ptr<Allocator>
get_allocator() const get_allocator() const

View file

@ -104,6 +104,7 @@ public:
options.template to_rcl_subscription_options<CallbackMessageT>(qos), options.template to_rcl_subscription_options<CallbackMessageT>(qos),
rclcpp::subscription_traits::is_serialized_subscription_argument<CallbackMessageT>::value), rclcpp::subscription_traits::is_serialized_subscription_argument<CallbackMessageT>::value),
any_callback_(callback), any_callback_(callback),
options_(options),
message_memory_strategy_(message_memory_strategy) message_memory_strategy_(message_memory_strategy)
{ {
if (options.event_callbacks.deadline_callback) { if (options.event_callbacks.deadline_callback) {
@ -302,6 +303,12 @@ private:
RCLCPP_DISABLE_COPY(Subscription) RCLCPP_DISABLE_COPY(Subscription)
AnySubscriptionCallback<CallbackMessageT, AllocatorT> any_callback_; AnySubscriptionCallback<CallbackMessageT, AllocatorT> any_callback_;
/// Copy of original options passed during construction.
/**
* It is important to save a copy of this so that the rmw payload which it
* may contain is kept alive for the duration of the subscription.
*/
const rclcpp::SubscriptionOptionsWithAllocator<AllocatorT> options_;
typename message_memory_strategy::MessageMemoryStrategy<CallbackMessageT, AllocatorT>::SharedPtr typename message_memory_strategy::MessageMemoryStrategy<CallbackMessageT, AllocatorT>::SharedPtr
message_memory_strategy_; message_memory_strategy_;
}; };

View file

@ -20,6 +20,7 @@
#include <vector> #include <vector>
#include "rclcpp/callback_group.hpp" #include "rclcpp/callback_group.hpp"
#include "rclcpp/detail/rmw_implementation_specific_subscription_payload.hpp"
#include "rclcpp/intra_process_setting.hpp" #include "rclcpp/intra_process_setting.hpp"
#include "rclcpp/qos.hpp" #include "rclcpp/qos.hpp"
#include "rclcpp/qos_event.hpp" #include "rclcpp/qos_event.hpp"
@ -33,12 +34,19 @@ struct SubscriptionOptionsBase
{ {
/// Callbacks for events related to this subscription. /// Callbacks for events related to this subscription.
SubscriptionEventCallbacks event_callbacks; SubscriptionEventCallbacks event_callbacks;
/// True to ignore local publications. /// True to ignore local publications.
bool ignore_local_publications = false; bool ignore_local_publications = false;
/// The callback group for this subscription. NULL to use the default callback group. /// The callback group for this subscription. NULL to use the default callback group.
rclcpp::callback_group::CallbackGroup::SharedPtr callback_group = nullptr; rclcpp::callback_group::CallbackGroup::SharedPtr callback_group = nullptr;
/// Setting to explicitly set intraprocess communications. /// Setting to explicitly set intraprocess communications.
IntraProcessSetting use_intra_process_comm = IntraProcessSetting::NodeDefault; IntraProcessSetting use_intra_process_comm = IntraProcessSetting::NodeDefault;
/// Optional RMW implementation specific payload to be used during creation of the subscription.
std::shared_ptr<rclcpp::detail::RMWImplementationSpecificSubscriptionPayload>
rmw_implementation_payload = nullptr;
}; };
/// Structure containing optional configuration for Subscriptions. /// Structure containing optional configuration for Subscriptions.
@ -61,13 +69,19 @@ struct SubscriptionOptionsWithAllocator : public SubscriptionOptionsBase
rcl_subscription_options_t rcl_subscription_options_t
to_rcl_subscription_options(const rclcpp::QoS & qos) const to_rcl_subscription_options(const rclcpp::QoS & qos) const
{ {
rcl_subscription_options_t result; rcl_subscription_options_t result = rcl_subscription_get_default_options();
using AllocatorTraits = std::allocator_traits<Allocator>; using AllocatorTraits = std::allocator_traits<Allocator>;
using MessageAllocatorT = typename AllocatorTraits::template rebind_alloc<MessageT>; using MessageAllocatorT = typename AllocatorTraits::template rebind_alloc<MessageT>;
auto message_alloc = std::make_shared<MessageAllocatorT>(*allocator.get()); auto message_alloc = std::make_shared<MessageAllocatorT>(*allocator.get());
result.allocator = allocator::get_rcl_allocator<MessageT>(*message_alloc); result.allocator = allocator::get_rcl_allocator<MessageT>(*message_alloc);
result.ignore_local_publications = this->ignore_local_publications;
result.qos = qos.get_rmw_qos_profile(); result.qos = qos.get_rmw_qos_profile();
result.rmw_subscription_options.ignore_local_publications = this->ignore_local_publications;
// Apply payload to rcl_subscription_options if necessary.
if (rmw_implementation_payload && rmw_implementation_payload->has_been_customized()) {
rmw_implementation_payload->modify_rmw_subscription_options(result.rmw_subscription_options);
}
return result; return result;
} }

View file

@ -0,0 +1,35 @@
// Copyright 2019 Open Source Robotics Foundation, Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#include <rclcpp/detail/rmw_implementation_specific_payload.hpp>
namespace rclcpp
{
namespace detail
{
bool
RMWImplementationSpecificPayload::has_been_customized() const
{
return nullptr != this->get_implementation_identifier();
}
const char *
RMWImplementationSpecificPayload::get_implementation_identifier() const
{
return nullptr;
}
} // namespace detail
} // namespace rclcpp

View file

@ -0,0 +1,33 @@
// Copyright 2019 Open Source Robotics Foundation, Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#include <rclcpp/detail/rmw_implementation_specific_publisher_payload.hpp>
#include "rcl/publisher.h"
namespace rclcpp
{
namespace detail
{
void
RMWImplementationSpecificPublisherPayload::modify_rmw_publisher_options(
rmw_publisher_options_t & rmw_publisher_options) const
{
// By default, do not mutate the rmw publisher options.
(void)rmw_publisher_options;
}
} // namespace detail
} // namespace rclcpp

View file

@ -0,0 +1,33 @@
// Copyright 2019 Open Source Robotics Foundation, Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#include <rclcpp/detail/rmw_implementation_specific_subscription_payload.hpp>
#include "rcl/subscription.h"
namespace rclcpp
{
namespace detail
{
void
RMWImplementationSpecificSubscriptionPayload::modify_rmw_subscription_options(
rmw_subscription_options_t & rmw_subscription_options) const
{
// By default, do not mutate the rmw subscription options.
(void)rmw_subscription_options;
}
} // namespace detail
} // namespace rclcpp