Compare commits
17 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
83c282a161 | ||
|
|
226044022a | ||
|
|
7e9ff5f4c7 | ||
|
|
64dd644469 | ||
|
|
322b5f5d79 | ||
|
|
e854bb29cd | ||
|
|
88ebea94e9 | ||
|
|
1e6767ac13 | ||
|
|
37e3688026 | ||
|
|
9b654942f9 | ||
|
|
f12e3c69dc | ||
|
|
bcc14755f9 | ||
|
|
4567b6ec80 | ||
|
|
0be8aa013e | ||
|
|
41d3a27437 | ||
|
|
c50f0c9c3d | ||
|
|
f8aea8cc51 |
@@ -2,6 +2,25 @@
|
||||
Changelog for package rclcpp
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
29.2.0 (2024-11-25)
|
||||
-------------------
|
||||
* accept custom allocator for LoanedMessage. (`#2672 <https://github.com/ros2/rclcpp/issues/2672>`_)
|
||||
* Contributors: Tomoya Fujita
|
||||
|
||||
29.1.0 (2024-11-20)
|
||||
-------------------
|
||||
* a couple of typo fixes in doc section for LoanedMessage. (`#2676 <https://github.com/ros2/rclcpp/issues/2676>`_)
|
||||
* Make sure callback_end tracepoint is triggered in AnyServiceCallback (`#2670 <https://github.com/ros2/rclcpp/issues/2670>`_)
|
||||
* Correct the incorrect comments in generic_client.hpp (`#2662 <https://github.com/ros2/rclcpp/issues/2662>`_)
|
||||
* Fix NodeOptions assignment operator (`#2656 <https://github.com/ros2/rclcpp/issues/2656>`_)
|
||||
* set QoS History KEEP_ALL explicitly for statistics publisher. (`#2650 <https://github.com/ros2/rclcpp/issues/2650>`_)
|
||||
* Fix test_intra_process_manager.cpp with rmw_zenoh_cpp (`#2653 <https://github.com/ros2/rclcpp/issues/2653>`_)
|
||||
* Fixed test_events_executors in zenoh (`#2643 <https://github.com/ros2/rclcpp/issues/2643>`_)
|
||||
* rmw_fastrtps supports service event gid uniqueness test. (`#2638 <https://github.com/ros2/rclcpp/issues/2638>`_)
|
||||
* print warning if event callback is not supported instead of passing exception. (`#2648 <https://github.com/ros2/rclcpp/issues/2648>`_)
|
||||
* Implement callback support of async_send_request for service generic client (`#2614 <https://github.com/ros2/rclcpp/issues/2614>`_)
|
||||
* Contributors: Alejandro Hernández Cordero, Barry Xu, Chris Lalancette, Christophe Bedard, Romain DESILLE, Tomoya Fujita
|
||||
|
||||
29.0.0 (2024-10-03)
|
||||
-------------------
|
||||
* Fixed test qos rmw zenoh (`#2639 <https://github.com/ros2/rclcpp/issues/2639>`_)
|
||||
|
||||
@@ -165,11 +165,13 @@ public:
|
||||
if (std::holds_alternative<SharedPtrDeferResponseCallback>(callback_)) {
|
||||
const auto & cb = std::get<SharedPtrDeferResponseCallback>(callback_);
|
||||
cb(request_header, std::move(request));
|
||||
TRACETOOLS_TRACEPOINT(callback_end, static_cast<const void *>(this));
|
||||
return nullptr;
|
||||
}
|
||||
if (std::holds_alternative<SharedPtrDeferResponseCallbackWithServiceHandle>(callback_)) {
|
||||
const auto & cb = std::get<SharedPtrDeferResponseCallbackWithServiceHandle>(callback_);
|
||||
cb(service_handle, request_header, std::move(request));
|
||||
TRACETOOLS_TRACEPOINT(callback_end, static_cast<const void *>(this));
|
||||
return nullptr;
|
||||
}
|
||||
// auto response = allocate_shared<typename ServiceT::Response, Allocator>();
|
||||
|
||||
@@ -19,6 +19,7 @@
|
||||
#include <memory>
|
||||
#include <future>
|
||||
#include <string>
|
||||
#include <tuple>
|
||||
#include <vector>
|
||||
#include <utility>
|
||||
|
||||
@@ -35,8 +36,8 @@ namespace rclcpp
|
||||
class GenericClient : public ClientBase
|
||||
{
|
||||
public:
|
||||
using Request = void *; // Serialized data pointer of request message
|
||||
using Response = void *; // Serialized data pointer of response message
|
||||
using Request = void *; // Deserialized data pointer of request message
|
||||
using Response = void *; // Deserialized data pointer of response message
|
||||
|
||||
using SharedResponse = std::shared_ptr<void>;
|
||||
|
||||
@@ -46,6 +47,8 @@ public:
|
||||
using Future = std::future<SharedResponse>;
|
||||
using SharedFuture = std::shared_future<SharedResponse>;
|
||||
|
||||
using CallbackType = std::function<void (SharedFuture)>;
|
||||
|
||||
RCLCPP_SMART_PTR_DEFINITIONS(GenericClient)
|
||||
|
||||
/// A convenient GenericClient::Future and request id pair.
|
||||
@@ -76,6 +79,20 @@ public:
|
||||
~FutureAndRequestId() = default;
|
||||
};
|
||||
|
||||
/// A convenient GenericClient::SharedFuture and request id pair.
|
||||
/**
|
||||
* Public members:
|
||||
* - future: a std::shared_future<SharedResponse>.
|
||||
* - request_id: the request id associated with the future.
|
||||
*
|
||||
* All the other methods are equivalent to the ones std::shared_future provides.
|
||||
*/
|
||||
struct SharedFutureAndRequestId
|
||||
: detail::FutureAndRequestId<std::shared_future<SharedResponse>>
|
||||
{
|
||||
using detail::FutureAndRequestId<std::shared_future<SharedResponse>>::FutureAndRequestId;
|
||||
};
|
||||
|
||||
GenericClient(
|
||||
rclcpp::node_interfaces::NodeBaseInterface * node_base,
|
||||
rclcpp::node_interfaces::NodeGraphInterface::SharedPtr node_graph,
|
||||
@@ -106,16 +123,16 @@ public:
|
||||
* If the future never completes,
|
||||
* e.g. the call to Executor::spin_until_future_complete() times out,
|
||||
* GenericClient::remove_pending_request() must be called to clean the client internal state.
|
||||
* Not doing so will make the `Client` instance to use more memory each time a response is not
|
||||
* received from the service server.
|
||||
* Not doing so will make the `GenericClient` instance to use more memory each time a response is
|
||||
* not received from the service server.
|
||||
*
|
||||
* ```cpp
|
||||
* auto future = client->async_send_request(my_request);
|
||||
* auto future = generic_client->async_send_request(my_request);
|
||||
* if (
|
||||
* rclcpp::FutureReturnCode::TIMEOUT ==
|
||||
* executor->spin_until_future_complete(future, timeout))
|
||||
* {
|
||||
* client->remove_pending_request(future);
|
||||
* generic_client->remove_pending_request(future);
|
||||
* // handle timeout
|
||||
* } else {
|
||||
* handle_response(future.get());
|
||||
@@ -129,6 +146,45 @@ public:
|
||||
FutureAndRequestId
|
||||
async_send_request(const Request request);
|
||||
|
||||
/// Send a request to the service server and schedule a callback in the executor.
|
||||
/**
|
||||
* Similar to the previous overload, but a callback will automatically be called when a response
|
||||
* is received.
|
||||
*
|
||||
* If the callback is never called, because we never got a reply for the service server,
|
||||
* remove_pending_request() has to be called with the returned request id or
|
||||
* prune_pending_requests().
|
||||
* Not doing so will make the `GenericClient` instance use more memory each time a response is not
|
||||
* received from the service server.
|
||||
* In this case, it's convenient to setup a timer to cleanup the pending requests.
|
||||
*
|
||||
* \param[in] request request to be send.
|
||||
* \param[in] cb callback that will be called when we get a response for this request.
|
||||
* \return the request id representing the request just sent.
|
||||
*/
|
||||
template<
|
||||
typename CallbackT,
|
||||
typename std::enable_if<
|
||||
rclcpp::function_traits::same_arguments<
|
||||
CallbackT,
|
||||
CallbackType
|
||||
>::value
|
||||
>::type * = nullptr
|
||||
>
|
||||
SharedFutureAndRequestId
|
||||
async_send_request(const Request request, CallbackT && cb)
|
||||
{
|
||||
Promise promise;
|
||||
auto shared_future = promise.get_future().share();
|
||||
auto req_id = async_send_request_impl(
|
||||
request,
|
||||
std::make_tuple(
|
||||
CallbackType{std::forward<CallbackT>(cb)},
|
||||
shared_future,
|
||||
std::move(promise)));
|
||||
return SharedFutureAndRequestId{std::move(shared_future), req_id};
|
||||
}
|
||||
|
||||
/// Clean all pending requests older than a time_point.
|
||||
/**
|
||||
* \param[in] time_point Requests that were sent before this point are going to be removed.
|
||||
@@ -149,15 +205,52 @@ public:
|
||||
pruned_requests);
|
||||
}
|
||||
|
||||
/// Clean all pending requests.
|
||||
/**
|
||||
* \return number of pending requests that were removed.
|
||||
*/
|
||||
RCLCPP_PUBLIC
|
||||
size_t
|
||||
prune_pending_requests();
|
||||
|
||||
/// Cleanup a pending request.
|
||||
/**
|
||||
* This notifies the client that we have waited long enough for a response from the server
|
||||
* to come, we have given up and we are not waiting for a response anymore.
|
||||
*
|
||||
* Not calling this will make the client start using more memory for each request
|
||||
* that never got a reply from the server.
|
||||
*
|
||||
* \param[in] request_id request id returned by async_send_request().
|
||||
* \return true when a pending request was removed, false if not (e.g. a response was received).
|
||||
*/
|
||||
RCLCPP_PUBLIC
|
||||
bool
|
||||
remove_pending_request(
|
||||
int64_t request_id);
|
||||
|
||||
/// Cleanup a pending request.
|
||||
/**
|
||||
* Convenient overload, same as:
|
||||
*
|
||||
* `GenericClient::remove_pending_request(this, future.request_id)`.
|
||||
*/
|
||||
RCLCPP_PUBLIC
|
||||
bool
|
||||
remove_pending_request(
|
||||
const FutureAndRequestId & future);
|
||||
|
||||
/// Cleanup a pending request.
|
||||
/**
|
||||
* Convenient overload, same as:
|
||||
*
|
||||
* `GenericClient::remove_pending_request(this, future.request_id)`.
|
||||
*/
|
||||
RCLCPP_PUBLIC
|
||||
bool
|
||||
remove_pending_request(
|
||||
const SharedFutureAndRequestId & future);
|
||||
|
||||
/// Take the next response for this client.
|
||||
/**
|
||||
* \sa ClientBase::take_type_erased_response().
|
||||
@@ -179,9 +272,12 @@ public:
|
||||
}
|
||||
|
||||
protected:
|
||||
using CallbackTypeValueVariant = std::tuple<CallbackType, SharedFuture, Promise>;
|
||||
using CallbackInfoVariant = std::variant<
|
||||
std::promise<SharedResponse>>; // Use variant for extension
|
||||
std::promise<SharedResponse>,
|
||||
CallbackTypeValueVariant>; // Use variant for extension
|
||||
|
||||
RCLCPP_PUBLIC
|
||||
int64_t
|
||||
async_send_request_impl(
|
||||
const Request request,
|
||||
|
||||
@@ -31,21 +31,20 @@ namespace rclcpp
|
||||
template<typename MessageT, typename AllocatorT = std::allocator<void>>
|
||||
class LoanedMessage
|
||||
{
|
||||
public:
|
||||
using MessageAllocatorTraits = rclcpp::allocator::AllocRebind<MessageT, AllocatorT>;
|
||||
using MessageAllocator = typename MessageAllocatorTraits::allocator_type;
|
||||
|
||||
public:
|
||||
/// Constructor of the LoanedMessage class.
|
||||
/**
|
||||
* The constructor of this class allocates memory for a given message type
|
||||
* and associates this with a given publisher.
|
||||
*
|
||||
* Given the publisher instance, a case differentiation is being performaned
|
||||
* which decides whether the underlying middleware is able to allocate the appropriate
|
||||
* memory for this message type or not.
|
||||
* In the case that the middleware can not loan messages, the passed in allocator instance
|
||||
* is being used to allocate the message within the scope of this class.
|
||||
* Otherwise, the allocator is being ignored and the allocation is solely performaned
|
||||
* The underlying middleware is queried to determine whether it is able to allocate the
|
||||
* appropriate memory for this message type or not.
|
||||
* In the case that the middleware cannot loan messages, the passed in allocator instance
|
||||
* is used to allocate the message within the scope of this class.
|
||||
* Otherwise, the allocator is ignored and the allocation is solely performed
|
||||
* in the underlying middleware with its appropriate allocation strategy.
|
||||
* The need for this arises as the user code can be written explicitly targeting a middleware
|
||||
* capable of loaning messages.
|
||||
@@ -53,12 +52,12 @@ public:
|
||||
* a middleware which doesn't support message loaning in which case the allocator will be used.
|
||||
*
|
||||
* \param[in] pub rclcpp::Publisher instance to which the memory belongs
|
||||
* \param[in] allocator Allocator instance in case middleware can not allocate messages
|
||||
* \param[in] allocator Allocator instance in case middleware cannot allocate messages
|
||||
* \throws anything rclcpp::exceptions::throw_from_rcl_error can throw.
|
||||
*/
|
||||
LoanedMessage(
|
||||
const rclcpp::PublisherBase & pub,
|
||||
std::allocator<MessageT> allocator)
|
||||
MessageAllocator allocator)
|
||||
: pub_(pub),
|
||||
message_(nullptr),
|
||||
message_allocator_(std::move(allocator))
|
||||
|
||||
@@ -80,7 +80,8 @@ struct SubscriptionOptionsBase
|
||||
|
||||
// An optional QoS which can provide topic_statistics with a stable QoS separate from
|
||||
// the subscription's current QoS settings which could be unstable.
|
||||
rclcpp::QoS qos = SystemDefaultsQoS();
|
||||
// Explicitly set the enough depth to avoid missing the statistics messages.
|
||||
rclcpp::QoS qos = SystemDefaultsQoS().keep_last(10);
|
||||
};
|
||||
|
||||
TopicStatisticsOptions topic_stats_options;
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
<?xml-model href="http://download.ros.org/schema/package_format2.xsd" schematypens="http://www.w3.org/2001/XMLSchema"?>
|
||||
<package format="2">
|
||||
<name>rclcpp</name>
|
||||
<version>29.0.0</version>
|
||||
<version>29.2.0</version>
|
||||
<description>The ROS client library in C++.</description>
|
||||
|
||||
<maintainer email="ivanpauno@ekumenlabs.com">Ivan Paunovic</maintainer>
|
||||
|
||||
@@ -109,6 +109,13 @@ GenericClient::handle_response(
|
||||
if (std::holds_alternative<Promise>(value)) {
|
||||
auto & promise = std::get<Promise>(value);
|
||||
promise.set_value(std::move(response));
|
||||
} else if (std::holds_alternative<CallbackTypeValueVariant>(value)) {
|
||||
auto & inner = std::get<CallbackTypeValueVariant>(value);
|
||||
const auto & callback = std::get<CallbackType>(inner);
|
||||
auto & promise = std::get<Promise>(inner);
|
||||
auto & future = std::get<SharedFuture>(inner);
|
||||
promise.set_value(std::move(response));
|
||||
callback(std::move(future));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -128,6 +135,18 @@ GenericClient::remove_pending_request(int64_t request_id)
|
||||
return pending_requests_.erase(request_id) != 0u;
|
||||
}
|
||||
|
||||
bool
|
||||
GenericClient::remove_pending_request(const FutureAndRequestId & future)
|
||||
{
|
||||
return this->remove_pending_request(future.request_id);
|
||||
}
|
||||
|
||||
bool
|
||||
GenericClient::remove_pending_request(const SharedFutureAndRequestId & future)
|
||||
{
|
||||
return this->remove_pending_request(future.request_id);
|
||||
}
|
||||
|
||||
std::optional<GenericClient::CallbackInfoVariant>
|
||||
GenericClient::get_and_erase_pending_request(int64_t request_number)
|
||||
{
|
||||
|
||||
@@ -80,6 +80,7 @@ NodeOptions::operator=(const NodeOptions & other)
|
||||
this->clock_type_ = other.clock_type_;
|
||||
this->clock_qos_ = other.clock_qos_;
|
||||
this->use_clock_thread_ = other.use_clock_thread_;
|
||||
this->enable_logger_service_ = other.enable_logger_service_;
|
||||
this->parameter_event_qos_ = other.parameter_event_qos_;
|
||||
this->rosout_qos_ = other.rosout_qos_;
|
||||
this->parameter_event_publisher_options_ = other.parameter_event_publisher_options_;
|
||||
|
||||
@@ -135,15 +135,28 @@ void
|
||||
PublisherBase::bind_event_callbacks(
|
||||
const PublisherEventCallbacks & event_callbacks, bool use_default_callbacks)
|
||||
{
|
||||
if (event_callbacks.deadline_callback) {
|
||||
this->add_event_handler(
|
||||
event_callbacks.deadline_callback,
|
||||
RCL_PUBLISHER_OFFERED_DEADLINE_MISSED);
|
||||
try {
|
||||
if (event_callbacks.deadline_callback) {
|
||||
this->add_event_handler(
|
||||
event_callbacks.deadline_callback,
|
||||
RCL_PUBLISHER_OFFERED_DEADLINE_MISSED);
|
||||
}
|
||||
} catch (const UnsupportedEventTypeException & /*exc*/) {
|
||||
RCLCPP_WARN(
|
||||
rclcpp::get_logger("rclcpp"),
|
||||
"Failed to add event handler for deadline; not supported");
|
||||
}
|
||||
if (event_callbacks.liveliness_callback) {
|
||||
this->add_event_handler(
|
||||
event_callbacks.liveliness_callback,
|
||||
RCL_PUBLISHER_LIVELINESS_LOST);
|
||||
|
||||
try {
|
||||
if (event_callbacks.liveliness_callback) {
|
||||
this->add_event_handler(
|
||||
event_callbacks.liveliness_callback,
|
||||
RCL_PUBLISHER_LIVELINESS_LOST);
|
||||
}
|
||||
} catch (const UnsupportedEventTypeException & /*exc*/) {
|
||||
RCLCPP_WARN(
|
||||
rclcpp::get_logger("rclcpp"),
|
||||
"Failed to add event handler for liveliness; not supported");
|
||||
}
|
||||
|
||||
QOSOfferedIncompatibleQoSCallbackType incompatible_qos_cb;
|
||||
@@ -160,9 +173,9 @@ PublisherBase::bind_event_callbacks(
|
||||
this->add_event_handler(incompatible_qos_cb, RCL_PUBLISHER_OFFERED_INCOMPATIBLE_QOS);
|
||||
}
|
||||
} catch (const UnsupportedEventTypeException & /*exc*/) {
|
||||
RCLCPP_DEBUG(
|
||||
RCLCPP_WARN(
|
||||
rclcpp::get_logger("rclcpp"),
|
||||
"Failed to add event handler for incompatible qos; wrong callback type");
|
||||
"Failed to add event handler for incompatible qos; not supported");
|
||||
}
|
||||
|
||||
IncompatibleTypeCallbackType incompatible_type_cb;
|
||||
@@ -179,14 +192,21 @@ PublisherBase::bind_event_callbacks(
|
||||
this->add_event_handler(incompatible_type_cb, RCL_PUBLISHER_INCOMPATIBLE_TYPE);
|
||||
}
|
||||
} catch (UnsupportedEventTypeException & /*exc*/) {
|
||||
RCLCPP_DEBUG(
|
||||
RCLCPP_WARN(
|
||||
rclcpp::get_logger("rclcpp"),
|
||||
"Failed to add event handler for incompatible type; wrong callback type");
|
||||
"Failed to add event handler for incompatible type; not supported");
|
||||
}
|
||||
if (event_callbacks.matched_callback) {
|
||||
this->add_event_handler(
|
||||
event_callbacks.matched_callback,
|
||||
RCL_PUBLISHER_MATCHED);
|
||||
|
||||
try {
|
||||
if (event_callbacks.matched_callback) {
|
||||
this->add_event_handler(
|
||||
event_callbacks.matched_callback,
|
||||
RCL_PUBLISHER_MATCHED);
|
||||
}
|
||||
} catch (const UnsupportedEventTypeException & /*exc*/) {
|
||||
RCLCPP_WARN(
|
||||
rclcpp::get_logger("rclcpp"),
|
||||
"Failed to add event handler for matched; not supported");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -112,16 +112,28 @@ void
|
||||
SubscriptionBase::bind_event_callbacks(
|
||||
const SubscriptionEventCallbacks & event_callbacks, bool use_default_callbacks)
|
||||
{
|
||||
if (event_callbacks.deadline_callback) {
|
||||
this->add_event_handler(
|
||||
event_callbacks.deadline_callback,
|
||||
RCL_SUBSCRIPTION_REQUESTED_DEADLINE_MISSED);
|
||||
try {
|
||||
if (event_callbacks.deadline_callback) {
|
||||
this->add_event_handler(
|
||||
event_callbacks.deadline_callback,
|
||||
RCL_SUBSCRIPTION_REQUESTED_DEADLINE_MISSED);
|
||||
}
|
||||
} catch (const UnsupportedEventTypeException & /*exc*/) {
|
||||
RCLCPP_WARN(
|
||||
rclcpp::get_logger("rclcpp"),
|
||||
"Failed to add event handler for deadline; not supported");
|
||||
}
|
||||
|
||||
if (event_callbacks.liveliness_callback) {
|
||||
this->add_event_handler(
|
||||
event_callbacks.liveliness_callback,
|
||||
RCL_SUBSCRIPTION_LIVELINESS_CHANGED);
|
||||
try {
|
||||
if (event_callbacks.liveliness_callback) {
|
||||
this->add_event_handler(
|
||||
event_callbacks.liveliness_callback,
|
||||
RCL_SUBSCRIPTION_LIVELINESS_CHANGED);
|
||||
}
|
||||
} catch (const UnsupportedEventTypeException & /*exc*/) {
|
||||
RCLCPP_WARN(
|
||||
rclcpp::get_logger("rclcpp"),
|
||||
"Failed to add event handler for liveliness; not supported");
|
||||
}
|
||||
|
||||
QOSRequestedIncompatibleQoSCallbackType incompatible_qos_cb;
|
||||
@@ -139,7 +151,9 @@ SubscriptionBase::bind_event_callbacks(
|
||||
this->add_event_handler(incompatible_qos_cb, RCL_SUBSCRIPTION_REQUESTED_INCOMPATIBLE_QOS);
|
||||
}
|
||||
} catch (const UnsupportedEventTypeException & /*exc*/) {
|
||||
// pass
|
||||
RCLCPP_WARN(
|
||||
rclcpp::get_logger("rclcpp"),
|
||||
"Failed to add event handler for incompatible qos; not supported");
|
||||
}
|
||||
|
||||
IncompatibleTypeCallbackType incompatible_type_cb;
|
||||
@@ -156,18 +170,33 @@ SubscriptionBase::bind_event_callbacks(
|
||||
this->add_event_handler(incompatible_type_cb, RCL_SUBSCRIPTION_INCOMPATIBLE_TYPE);
|
||||
}
|
||||
} catch (UnsupportedEventTypeException & /*exc*/) {
|
||||
// pass
|
||||
RCLCPP_WARN(
|
||||
rclcpp::get_logger("rclcpp"),
|
||||
"Failed to add event handler for incompatible type; not supported");
|
||||
}
|
||||
|
||||
if (event_callbacks.message_lost_callback) {
|
||||
this->add_event_handler(
|
||||
event_callbacks.message_lost_callback,
|
||||
RCL_SUBSCRIPTION_MESSAGE_LOST);
|
||||
try {
|
||||
if (event_callbacks.message_lost_callback) {
|
||||
this->add_event_handler(
|
||||
event_callbacks.message_lost_callback,
|
||||
RCL_SUBSCRIPTION_MESSAGE_LOST);
|
||||
}
|
||||
} catch (const UnsupportedEventTypeException & /*exc*/) {
|
||||
RCLCPP_WARN(
|
||||
rclcpp::get_logger("rclcpp"),
|
||||
"Failed to add event handler for message lost; not supported");
|
||||
}
|
||||
if (event_callbacks.matched_callback) {
|
||||
this->add_event_handler(
|
||||
event_callbacks.matched_callback,
|
||||
RCL_SUBSCRIPTION_MATCHED);
|
||||
|
||||
try {
|
||||
if (event_callbacks.matched_callback) {
|
||||
this->add_event_handler(
|
||||
event_callbacks.matched_callback,
|
||||
RCL_SUBSCRIPTION_MATCHED);
|
||||
}
|
||||
} catch (const UnsupportedEventTypeException & /*exc*/) {
|
||||
RCLCPP_WARN(
|
||||
rclcpp::get_logger("rclcpp"),
|
||||
"Failed to add event handler for matched; not supported");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -555,7 +555,7 @@ if(TARGET test_executor_notify_waitable)
|
||||
target_link_libraries(test_executor_notify_waitable ${PROJECT_NAME} mimick rcpputils::rcpputils)
|
||||
endif()
|
||||
|
||||
ament_add_gtest(test_events_executor executors/test_events_executor.cpp TIMEOUT 5)
|
||||
ament_add_gtest(test_events_executor executors/test_events_executor.cpp TIMEOUT 60)
|
||||
if(TARGET test_events_executor)
|
||||
target_link_libraries(test_events_executor ${PROJECT_NAME} ${test_msgs_TARGETS})
|
||||
endif()
|
||||
|
||||
@@ -479,14 +479,21 @@ TEST_F(TestEventsExecutor, test_default_incompatible_qos_callbacks)
|
||||
const auto timeout = std::chrono::seconds(10);
|
||||
ex.spin_until_future_complete(log_msgs_future, timeout);
|
||||
|
||||
EXPECT_EQ(
|
||||
"New subscription discovered on topic '/test_topic', requesting incompatible QoS. "
|
||||
"No messages will be sent to it. Last incompatible policy: DURABILITY_QOS_POLICY",
|
||||
pub_log_msg);
|
||||
EXPECT_EQ(
|
||||
"New publisher discovered on topic '/test_topic', offering incompatible QoS. "
|
||||
"No messages will be sent to it. Last incompatible policy: DURABILITY_QOS_POLICY",
|
||||
sub_log_msg);
|
||||
rclcpp::QoSCheckCompatibleResult qos_compatible = rclcpp::qos_check_compatible(
|
||||
publisher->get_actual_qos(), subscription->get_actual_qos());
|
||||
if (qos_compatible.compatibility == rclcpp::QoSCompatibility::Error) {
|
||||
EXPECT_EQ(
|
||||
"New subscription discovered on topic '/test_topic', requesting incompatible QoS. "
|
||||
"No messages will be sent to it. Last incompatible policy: DURABILITY_QOS_POLICY",
|
||||
pub_log_msg);
|
||||
EXPECT_EQ(
|
||||
"New publisher discovered on topic '/test_topic', offering incompatible QoS. "
|
||||
"No messages will be sent to it. Last incompatible policy: DURABILITY_QOS_POLICY",
|
||||
sub_log_msg);
|
||||
} else {
|
||||
EXPECT_EQ("", pub_log_msg);
|
||||
EXPECT_EQ("", sub_log_msg);
|
||||
}
|
||||
|
||||
rcutils_logging_set_output_handler(original_output_handler);
|
||||
}
|
||||
|
||||
@@ -14,6 +14,8 @@
|
||||
|
||||
#include <gtest/gtest.h>
|
||||
|
||||
#include <chrono>
|
||||
#include <cstdint>
|
||||
#include <string>
|
||||
#include <memory>
|
||||
#include <utility>
|
||||
@@ -28,6 +30,7 @@
|
||||
#include "../mocking_utils/patch.hpp"
|
||||
|
||||
#include "test_msgs/srv/empty.hpp"
|
||||
#include "test_msgs/srv/basic_types.hpp"
|
||||
|
||||
using namespace std::chrono_literals;
|
||||
|
||||
@@ -228,3 +231,69 @@ TEST_F(TestGenericClientSub, construction_and_destruction) {
|
||||
}, rclcpp::exceptions::InvalidServiceNameError);
|
||||
}
|
||||
}
|
||||
|
||||
TEST_F(TestGenericClientSub, async_send_request_with_request) {
|
||||
const std::string service_name = "test_service";
|
||||
int64_t expected_change = 1111;
|
||||
|
||||
auto client = node->create_generic_client(service_name, "test_msgs/srv/BasicTypes");
|
||||
|
||||
auto callback = [&expected_change](
|
||||
const test_msgs::srv::BasicTypes::Request::SharedPtr request,
|
||||
test_msgs::srv::BasicTypes::Response::SharedPtr response) {
|
||||
response->int64_value = request->int64_value + expected_change;
|
||||
};
|
||||
|
||||
auto service =
|
||||
node->create_service<test_msgs::srv::BasicTypes>(service_name, std::move(callback));
|
||||
|
||||
ASSERT_TRUE(client->wait_for_service(std::chrono::seconds(5)));
|
||||
ASSERT_TRUE(client->service_is_ready());
|
||||
|
||||
test_msgs::srv::BasicTypes::Request request;
|
||||
request.int64_value = 12345678;
|
||||
|
||||
auto future = client->async_send_request(static_cast<void *>(&request));
|
||||
rclcpp::spin_until_future_complete(
|
||||
node->get_node_base_interface(), future, std::chrono::seconds(5));
|
||||
ASSERT_TRUE(future.valid());
|
||||
auto get_untyped_response = future.get();
|
||||
auto typed_response =
|
||||
static_cast<test_msgs::srv::BasicTypes::Response *>(get_untyped_response.get());
|
||||
EXPECT_EQ(typed_response->int64_value, (request.int64_value + expected_change));
|
||||
}
|
||||
|
||||
TEST_F(TestGenericClientSub, async_send_request_with_request_and_callback) {
|
||||
const std::string service_name = "test_service";
|
||||
int64_t expected_change = 2222;
|
||||
|
||||
auto client = node->create_generic_client(service_name, "test_msgs/srv/BasicTypes");
|
||||
|
||||
auto server_callback = [&expected_change](
|
||||
const test_msgs::srv::BasicTypes::Request::SharedPtr request,
|
||||
test_msgs::srv::BasicTypes::Response::SharedPtr response) {
|
||||
response->int64_value = request->int64_value + expected_change;
|
||||
};
|
||||
|
||||
auto service =
|
||||
node->create_service<test_msgs::srv::BasicTypes>(service_name, std::move(server_callback));
|
||||
|
||||
ASSERT_TRUE(client->wait_for_service(std::chrono::seconds(5)));
|
||||
ASSERT_TRUE(client->service_is_ready());
|
||||
|
||||
test_msgs::srv::BasicTypes::Request request;
|
||||
request.int64_value = 12345678;
|
||||
|
||||
auto client_callback = [&request, &expected_change](
|
||||
rclcpp::GenericClient::SharedFuture future) {
|
||||
auto untyped_response = future.get();
|
||||
auto typed_response =
|
||||
static_cast<test_msgs::srv::BasicTypes::Response *>(untyped_response.get());
|
||||
EXPECT_EQ(typed_response->int64_value, (request.int64_value + expected_change));
|
||||
};
|
||||
|
||||
auto future =
|
||||
client->async_send_request(static_cast<void *>(&request), client_callback);
|
||||
rclcpp::spin_until_future_complete(
|
||||
node->get_node_base_interface(), future, std::chrono::seconds(5));
|
||||
}
|
||||
|
||||
@@ -123,6 +123,7 @@ public:
|
||||
return result;
|
||||
}
|
||||
|
||||
private:
|
||||
// need to store the messages somewhere otherwise the memory address will be reused
|
||||
ConstMessageSharedPtr shared_msg;
|
||||
MessageUniquePtr unique_msg;
|
||||
@@ -158,9 +159,9 @@ class PublisherBase
|
||||
public:
|
||||
RCLCPP_SMART_PTR_DEFINITIONS(PublisherBase)
|
||||
|
||||
explicit PublisherBase(rclcpp::QoS qos = rclcpp::QoS(10))
|
||||
: qos_profile(qos),
|
||||
topic_name("topic")
|
||||
explicit PublisherBase(const std::string & topic, const rclcpp::QoS & qos)
|
||||
: topic_name(topic),
|
||||
qos_profile(qos)
|
||||
{}
|
||||
|
||||
virtual ~PublisherBase()
|
||||
@@ -205,10 +206,12 @@ public:
|
||||
return false;
|
||||
}
|
||||
|
||||
rclcpp::QoS qos_profile;
|
||||
std::string topic_name;
|
||||
uint64_t intra_process_publisher_id_;
|
||||
IntraProcessManagerWeakPtr weak_ipm_;
|
||||
|
||||
private:
|
||||
std::string topic_name;
|
||||
rclcpp::QoS qos_profile;
|
||||
};
|
||||
|
||||
template<typename T, typename Alloc = std::allocator<void>>
|
||||
@@ -223,8 +226,8 @@ public:
|
||||
|
||||
RCLCPP_SMART_PTR_DEFINITIONS(Publisher<T, Alloc>)
|
||||
|
||||
explicit Publisher(rclcpp::QoS qos = rclcpp::QoS(10))
|
||||
: PublisherBase(qos)
|
||||
explicit Publisher(const std::string & topic, const rclcpp::QoS & qos)
|
||||
: PublisherBase(topic, qos)
|
||||
{
|
||||
auto allocator = std::make_shared<Alloc>();
|
||||
message_allocator_ = std::make_shared<MessageAlloc>(*allocator.get());
|
||||
@@ -258,9 +261,9 @@ public:
|
||||
|
||||
explicit SubscriptionIntraProcessBase(
|
||||
rclcpp::Context::SharedPtr context,
|
||||
const std::string & topic = "topic",
|
||||
rclcpp::QoS qos = rclcpp::QoS(10))
|
||||
: qos_profile(qos), topic_name(topic)
|
||||
const std::string & topic,
|
||||
const rclcpp::QoS & qos)
|
||||
: topic_name(topic), qos_profile(qos)
|
||||
{
|
||||
(void)context;
|
||||
}
|
||||
@@ -292,8 +295,8 @@ public:
|
||||
size_t
|
||||
available_capacity() const = 0;
|
||||
|
||||
rclcpp::QoS qos_profile;
|
||||
std::string topic_name;
|
||||
rclcpp::QoS qos_profile;
|
||||
};
|
||||
|
||||
template<
|
||||
@@ -307,8 +310,8 @@ class SubscriptionIntraProcessBuffer : public SubscriptionIntraProcessBase
|
||||
public:
|
||||
RCLCPP_SMART_PTR_DEFINITIONS(SubscriptionIntraProcessBuffer)
|
||||
|
||||
explicit SubscriptionIntraProcessBuffer(rclcpp::QoS qos)
|
||||
: SubscriptionIntraProcessBase(nullptr, "topic", qos), take_shared_method(false)
|
||||
explicit SubscriptionIntraProcessBuffer(const std::string & topic, const rclcpp::QoS & qos)
|
||||
: SubscriptionIntraProcessBase(nullptr, topic, qos), take_shared_method(false)
|
||||
{
|
||||
buffer = std::make_unique<rclcpp::experimental::buffers::mock::IntraProcessBuffer<MessageT>>();
|
||||
}
|
||||
@@ -375,8 +378,8 @@ class SubscriptionIntraProcess : public SubscriptionIntraProcessBuffer<
|
||||
public:
|
||||
RCLCPP_SMART_PTR_DEFINITIONS(SubscriptionIntraProcess)
|
||||
|
||||
explicit SubscriptionIntraProcess(rclcpp::QoS qos = rclcpp::QoS(10))
|
||||
: SubscriptionIntraProcessBuffer<MessageT, Alloc, Deleter>(qos)
|
||||
explicit SubscriptionIntraProcess(const std::string & topic, const rclcpp::QoS & qos)
|
||||
: SubscriptionIntraProcessBuffer<MessageT, Alloc, Deleter>(topic, qos)
|
||||
{
|
||||
}
|
||||
};
|
||||
@@ -466,12 +469,11 @@ TEST(TestIntraProcessManager, add_pub_sub) {
|
||||
|
||||
auto ipm = std::make_shared<IntraProcessManagerT>();
|
||||
|
||||
auto p1 = std::make_shared<PublisherT>(rclcpp::QoS(10).best_effort());
|
||||
auto p1 = std::make_shared<PublisherT>("topic", rclcpp::QoS(10).best_effort());
|
||||
|
||||
auto p2 = std::make_shared<PublisherT>(rclcpp::QoS(10).best_effort());
|
||||
p2->topic_name = "different_topic_name";
|
||||
auto p2 = std::make_shared<PublisherT>("different_topic_name", rclcpp::QoS(10).best_effort());
|
||||
|
||||
auto s1 = std::make_shared<SubscriptionIntraProcessT>(rclcpp::QoS(10).best_effort());
|
||||
auto s1 = std::make_shared<SubscriptionIntraProcessT>("topic", rclcpp::QoS(10).best_effort());
|
||||
|
||||
auto p1_id = ipm->add_publisher(p1);
|
||||
auto p2_id = ipm->add_publisher(p2);
|
||||
@@ -480,24 +482,42 @@ TEST(TestIntraProcessManager, add_pub_sub) {
|
||||
bool unique_ids = p1_id != p2_id && p2_id != s1_id;
|
||||
ASSERT_TRUE(unique_ids);
|
||||
|
||||
// p1 has 1 subcription, s1
|
||||
size_t p1_subs = ipm->get_subscription_count(p1_id);
|
||||
// p2 has 0 subscriptions
|
||||
size_t p2_subs = ipm->get_subscription_count(p2_id);
|
||||
// Non-existent publisher_id has 0 subscriptions
|
||||
size_t non_existing_pub_subs = ipm->get_subscription_count(42);
|
||||
ASSERT_EQ(1u, p1_subs);
|
||||
ASSERT_EQ(0u, p2_subs);
|
||||
ASSERT_EQ(0u, non_existing_pub_subs);
|
||||
|
||||
auto p3 = std::make_shared<PublisherT>(rclcpp::QoS(10).reliable());
|
||||
auto p3 = std::make_shared<PublisherT>("topic", rclcpp::QoS(10).reliable());
|
||||
|
||||
auto s2 = std::make_shared<SubscriptionIntraProcessT>(rclcpp::QoS(10).reliable());
|
||||
auto s2 = std::make_shared<SubscriptionIntraProcessT>("topic", rclcpp::QoS(10).reliable());
|
||||
|
||||
// s2 may be able to communicate with p1 depending on the RMW
|
||||
auto s2_id = ipm->template add_subscription<MessageT>(s2);
|
||||
// p3 can definitely communicate with s2, may be able to communicate with s1 depending on the RMW
|
||||
auto p3_id = ipm->add_publisher(p3);
|
||||
|
||||
// p1 definitely matches subscription s1, since the topic name and QoS match exactly.
|
||||
// If the RMW can match best-effort publishers to reliable subscriptions (like Zenoh can),
|
||||
// then p1 will also match s2.
|
||||
p1_subs = ipm->get_subscription_count(p1_id);
|
||||
// No subscriptions with a topic name of "different_topic_name" were added.
|
||||
p2_subs = ipm->get_subscription_count(p2_id);
|
||||
// On all current RMWs (DDS and Zenoh), a reliable publisher like p3 can communicate with both
|
||||
// reliable and best-effort subscriptions (s1 and s2).
|
||||
size_t p3_subs = ipm->get_subscription_count(p3_id);
|
||||
ASSERT_EQ(1u, p1_subs);
|
||||
|
||||
rclcpp::QoSCheckCompatibleResult qos_compatible =
|
||||
rclcpp::qos_check_compatible(p1->get_actual_qos(), s2->get_actual_qos());
|
||||
if (qos_compatible.compatibility == rclcpp::QoSCompatibility::Error) {
|
||||
ASSERT_EQ(1u, p1_subs);
|
||||
} else {
|
||||
ASSERT_EQ(2u, p1_subs);
|
||||
}
|
||||
ASSERT_EQ(0u, p2_subs);
|
||||
ASSERT_EQ(2u, p3_subs);
|
||||
|
||||
@@ -528,11 +548,11 @@ TEST(TestIntraProcessManager, single_subscription) {
|
||||
|
||||
auto ipm = std::make_shared<IntraProcessManagerT>();
|
||||
|
||||
auto p1 = std::make_shared<PublisherT>();
|
||||
auto p1 = std::make_shared<PublisherT>("topic", rclcpp::QoS(10));
|
||||
auto p1_id = ipm->add_publisher(p1);
|
||||
p1->set_intra_process_manager(p1_id, ipm);
|
||||
|
||||
auto s1 = std::make_shared<SubscriptionIntraProcessT>();
|
||||
auto s1 = std::make_shared<SubscriptionIntraProcessT>("topic", rclcpp::QoS(10));
|
||||
s1->take_shared_method = false;
|
||||
auto s1_id = ipm->template add_subscription<MessageT>(s1);
|
||||
|
||||
@@ -543,7 +563,7 @@ TEST(TestIntraProcessManager, single_subscription) {
|
||||
ASSERT_EQ(original_message_pointer, received_message_pointer_1);
|
||||
|
||||
ipm->remove_subscription(s1_id);
|
||||
auto s2 = std::make_shared<SubscriptionIntraProcessT>();
|
||||
auto s2 = std::make_shared<SubscriptionIntraProcessT>("topic", rclcpp::QoS(10));
|
||||
s2->take_shared_method = true;
|
||||
auto s2_id = ipm->template add_subscription<MessageT>(s2);
|
||||
(void)s2_id;
|
||||
@@ -582,15 +602,15 @@ TEST(TestIntraProcessManager, multiple_subscriptions_same_type) {
|
||||
|
||||
auto ipm = std::make_shared<IntraProcessManagerT>();
|
||||
|
||||
auto p1 = std::make_shared<PublisherT>();
|
||||
auto p1 = std::make_shared<PublisherT>("topic", rclcpp::QoS(10));
|
||||
auto p1_id = ipm->add_publisher(p1);
|
||||
p1->set_intra_process_manager(p1_id, ipm);
|
||||
|
||||
auto s1 = std::make_shared<SubscriptionIntraProcessT>();
|
||||
auto s1 = std::make_shared<SubscriptionIntraProcessT>("topic", rclcpp::QoS(10));
|
||||
s1->take_shared_method = false;
|
||||
auto s1_id = ipm->template add_subscription<MessageT>(s1);
|
||||
|
||||
auto s2 = std::make_shared<SubscriptionIntraProcessT>();
|
||||
auto s2 = std::make_shared<SubscriptionIntraProcessT>("topic", rclcpp::QoS(10));
|
||||
s2->take_shared_method = false;
|
||||
auto s2_id = ipm->template add_subscription<MessageT>(s2);
|
||||
|
||||
@@ -606,11 +626,11 @@ TEST(TestIntraProcessManager, multiple_subscriptions_same_type) {
|
||||
ipm->remove_subscription(s1_id);
|
||||
ipm->remove_subscription(s2_id);
|
||||
|
||||
auto s3 = std::make_shared<SubscriptionIntraProcessT>();
|
||||
auto s3 = std::make_shared<SubscriptionIntraProcessT>("topic", rclcpp::QoS(10));
|
||||
s3->take_shared_method = true;
|
||||
auto s3_id = ipm->template add_subscription<MessageT>(s3);
|
||||
|
||||
auto s4 = std::make_shared<SubscriptionIntraProcessT>();
|
||||
auto s4 = std::make_shared<SubscriptionIntraProcessT>("topic", rclcpp::QoS(10));
|
||||
s4->take_shared_method = true;
|
||||
auto s4_id = ipm->template add_subscription<MessageT>(s4);
|
||||
|
||||
@@ -625,11 +645,11 @@ TEST(TestIntraProcessManager, multiple_subscriptions_same_type) {
|
||||
ipm->remove_subscription(s3_id);
|
||||
ipm->remove_subscription(s4_id);
|
||||
|
||||
auto s5 = std::make_shared<SubscriptionIntraProcessT>();
|
||||
auto s5 = std::make_shared<SubscriptionIntraProcessT>("topic", rclcpp::QoS(10));
|
||||
s5->take_shared_method = false;
|
||||
auto s5_id = ipm->template add_subscription<MessageT>(s5);
|
||||
|
||||
auto s6 = std::make_shared<SubscriptionIntraProcessT>();
|
||||
auto s6 = std::make_shared<SubscriptionIntraProcessT>("topic", rclcpp::QoS(10));
|
||||
s6->take_shared_method = false;
|
||||
auto s6_id = ipm->template add_subscription<MessageT>(s6);
|
||||
|
||||
@@ -645,12 +665,12 @@ TEST(TestIntraProcessManager, multiple_subscriptions_same_type) {
|
||||
ipm->remove_subscription(s5_id);
|
||||
ipm->remove_subscription(s6_id);
|
||||
|
||||
auto s7 = std::make_shared<SubscriptionIntraProcessT>();
|
||||
auto s7 = std::make_shared<SubscriptionIntraProcessT>("topic", rclcpp::QoS(10));
|
||||
s7->take_shared_method = true;
|
||||
auto s7_id = ipm->template add_subscription<MessageT>(s7);
|
||||
(void)s7_id;
|
||||
|
||||
auto s8 = std::make_shared<SubscriptionIntraProcessT>();
|
||||
auto s8 = std::make_shared<SubscriptionIntraProcessT>("topic", rclcpp::QoS(10));
|
||||
s8->take_shared_method = true;
|
||||
auto s8_id = ipm->template add_subscription<MessageT>(s8);
|
||||
(void)s8_id;
|
||||
@@ -688,15 +708,15 @@ TEST(TestIntraProcessManager, multiple_subscriptions_different_type) {
|
||||
|
||||
auto ipm = std::make_shared<IntraProcessManagerT>();
|
||||
|
||||
auto p1 = std::make_shared<PublisherT>();
|
||||
auto p1 = std::make_shared<PublisherT>("topic", rclcpp::QoS(10));
|
||||
auto p1_id = ipm->add_publisher(p1);
|
||||
p1->set_intra_process_manager(p1_id, ipm);
|
||||
|
||||
auto s1 = std::make_shared<SubscriptionIntraProcessT>();
|
||||
auto s1 = std::make_shared<SubscriptionIntraProcessT>("topic", rclcpp::QoS(10));
|
||||
s1->take_shared_method = true;
|
||||
auto s1_id = ipm->template add_subscription<MessageT>(s1);
|
||||
|
||||
auto s2 = std::make_shared<SubscriptionIntraProcessT>();
|
||||
auto s2 = std::make_shared<SubscriptionIntraProcessT>("topic", rclcpp::QoS(10));
|
||||
s2->take_shared_method = false;
|
||||
auto s2_id = ipm->template add_subscription<MessageT>(s2);
|
||||
|
||||
@@ -711,15 +731,15 @@ TEST(TestIntraProcessManager, multiple_subscriptions_different_type) {
|
||||
ipm->remove_subscription(s1_id);
|
||||
ipm->remove_subscription(s2_id);
|
||||
|
||||
auto s3 = std::make_shared<SubscriptionIntraProcessT>();
|
||||
auto s3 = std::make_shared<SubscriptionIntraProcessT>("topic", rclcpp::QoS(10));
|
||||
s3->take_shared_method = false;
|
||||
auto s3_id = ipm->template add_subscription<MessageT>(s3);
|
||||
|
||||
auto s4 = std::make_shared<SubscriptionIntraProcessT>();
|
||||
auto s4 = std::make_shared<SubscriptionIntraProcessT>("topic", rclcpp::QoS(10));
|
||||
s4->take_shared_method = false;
|
||||
auto s4_id = ipm->template add_subscription<MessageT>(s4);
|
||||
|
||||
auto s5 = std::make_shared<SubscriptionIntraProcessT>();
|
||||
auto s5 = std::make_shared<SubscriptionIntraProcessT>("topic", rclcpp::QoS(10));
|
||||
s5->take_shared_method = true;
|
||||
auto s5_id = ipm->template add_subscription<MessageT>(s5);
|
||||
|
||||
@@ -743,19 +763,19 @@ TEST(TestIntraProcessManager, multiple_subscriptions_different_type) {
|
||||
ipm->remove_subscription(s4_id);
|
||||
ipm->remove_subscription(s5_id);
|
||||
|
||||
auto s6 = std::make_shared<SubscriptionIntraProcessT>();
|
||||
auto s6 = std::make_shared<SubscriptionIntraProcessT>("topic", rclcpp::QoS(10));
|
||||
s6->take_shared_method = true;
|
||||
auto s6_id = ipm->template add_subscription<MessageT>(s6);
|
||||
|
||||
auto s7 = std::make_shared<SubscriptionIntraProcessT>();
|
||||
auto s7 = std::make_shared<SubscriptionIntraProcessT>("topic", rclcpp::QoS(10));
|
||||
s7->take_shared_method = true;
|
||||
auto s7_id = ipm->template add_subscription<MessageT>(s7);
|
||||
|
||||
auto s8 = std::make_shared<SubscriptionIntraProcessT>();
|
||||
auto s8 = std::make_shared<SubscriptionIntraProcessT>("topic", rclcpp::QoS(10));
|
||||
s8->take_shared_method = false;
|
||||
auto s8_id = ipm->template add_subscription<MessageT>(s8);
|
||||
|
||||
auto s9 = std::make_shared<SubscriptionIntraProcessT>();
|
||||
auto s9 = std::make_shared<SubscriptionIntraProcessT>("topic", rclcpp::QoS(10));
|
||||
s9->take_shared_method = false;
|
||||
auto s9_id = ipm->template add_subscription<MessageT>(s9);
|
||||
|
||||
@@ -781,12 +801,12 @@ TEST(TestIntraProcessManager, multiple_subscriptions_different_type) {
|
||||
ipm->remove_subscription(s8_id);
|
||||
ipm->remove_subscription(s9_id);
|
||||
|
||||
auto s10 = std::make_shared<SubscriptionIntraProcessT>();
|
||||
auto s10 = std::make_shared<SubscriptionIntraProcessT>("topic", rclcpp::QoS(10));
|
||||
s10->take_shared_method = false;
|
||||
auto s10_id = ipm->template add_subscription<MessageT>(s10);
|
||||
(void)s10_id;
|
||||
|
||||
auto s11 = std::make_shared<SubscriptionIntraProcessT>();
|
||||
auto s11 = std::make_shared<SubscriptionIntraProcessT>("topic", rclcpp::QoS(10));
|
||||
s11->take_shared_method = true;
|
||||
auto s11_id = ipm->template add_subscription<MessageT>(s11);
|
||||
(void)s11_id;
|
||||
@@ -831,10 +851,12 @@ TEST(TestIntraProcessManager, lowest_available_capacity) {
|
||||
|
||||
auto ipm = std::make_shared<IntraProcessManagerT>();
|
||||
|
||||
auto p1 = std::make_shared<PublisherT>(rclcpp::QoS(history_depth).best_effort());
|
||||
auto p1 = std::make_shared<PublisherT>("topic", rclcpp::QoS(history_depth).best_effort());
|
||||
|
||||
auto s1 = std::make_shared<SubscriptionIntraProcessT>(rclcpp::QoS(history_depth).best_effort());
|
||||
auto s2 = std::make_shared<SubscriptionIntraProcessT>(rclcpp::QoS(history_depth).best_effort());
|
||||
auto s1 =
|
||||
std::make_shared<SubscriptionIntraProcessT>("topic", rclcpp::QoS(history_depth).best_effort());
|
||||
auto s2 =
|
||||
std::make_shared<SubscriptionIntraProcessT>("topic", rclcpp::QoS(history_depth).best_effort());
|
||||
|
||||
auto p1_id = ipm->add_publisher(p1);
|
||||
p1->set_intra_process_manager(p1_id, ipm);
|
||||
@@ -902,7 +924,7 @@ TEST(TestIntraProcessManager, transient_local_invalid_buffer) {
|
||||
|
||||
auto ipm = std::make_shared<IntraProcessManagerT>();
|
||||
|
||||
auto p1 = std::make_shared<PublisherT>(rclcpp::QoS(history_depth).transient_local());
|
||||
auto p1 = std::make_shared<PublisherT>("topic", rclcpp::QoS(history_depth).transient_local());
|
||||
|
||||
ASSERT_THROW(
|
||||
{
|
||||
@@ -926,14 +948,14 @@ TEST(TestIntraProcessManager, transient_local) {
|
||||
|
||||
auto ipm = std::make_shared<IntraProcessManagerT>();
|
||||
|
||||
auto p1 = std::make_shared<PublisherT>(rclcpp::QoS(history_depth).transient_local());
|
||||
auto p1 = std::make_shared<PublisherT>("topic", rclcpp::QoS(history_depth).transient_local());
|
||||
|
||||
auto s1 =
|
||||
std::make_shared<SubscriptionIntraProcessT>(rclcpp::QoS(history_depth).transient_local());
|
||||
auto s2 =
|
||||
std::make_shared<SubscriptionIntraProcessT>(rclcpp::QoS(history_depth).transient_local());
|
||||
auto s3 =
|
||||
std::make_shared<SubscriptionIntraProcessT>(rclcpp::QoS(history_depth).transient_local());
|
||||
auto s1 = std::make_shared<SubscriptionIntraProcessT>(
|
||||
"topic", rclcpp::QoS(history_depth).transient_local());
|
||||
auto s2 = std::make_shared<SubscriptionIntraProcessT>(
|
||||
"topic", rclcpp::QoS(history_depth).transient_local());
|
||||
auto s3 = std::make_shared<SubscriptionIntraProcessT>(
|
||||
"topic", rclcpp::QoS(history_depth).transient_local());
|
||||
|
||||
s1->take_shared_method = false;
|
||||
s2->take_shared_method = true;
|
||||
|
||||
@@ -200,6 +200,57 @@ TEST(TestNodeOptions, copy) {
|
||||
rcl_arguments_get_count_unparsed(&other_rcl_options->arguments),
|
||||
rcl_arguments_get_count_unparsed(&rcl_options->arguments));
|
||||
}
|
||||
|
||||
{
|
||||
// The following scope test is missing:
|
||||
// "arguments" because it is already tested in the above scopes
|
||||
// "parameter_event_publisher_options" because it can not be directly compared with EXPECT_EQ
|
||||
// "allocator" because it can not be directly compared with EXPECT_EQ
|
||||
|
||||
// We separate attribute modification from variable initialisation (copy assignment operator)
|
||||
// to be sure the "non_default_options"'s properties are correctly set before testing the
|
||||
// assignment operator.
|
||||
auto non_default_options = rclcpp::NodeOptions();
|
||||
non_default_options
|
||||
.parameter_overrides({rclcpp::Parameter("foo", 0), rclcpp::Parameter("bar", "1")})
|
||||
.use_global_arguments(false)
|
||||
.enable_rosout(false)
|
||||
.use_intra_process_comms(true)
|
||||
.enable_topic_statistics(true)
|
||||
.start_parameter_services(false)
|
||||
.enable_logger_service(true)
|
||||
.start_parameter_event_publisher(false)
|
||||
.clock_type(RCL_SYSTEM_TIME)
|
||||
.clock_qos(rclcpp::SensorDataQoS())
|
||||
.use_clock_thread(false)
|
||||
.parameter_event_qos(rclcpp::ClockQoS())
|
||||
.rosout_qos(rclcpp::ParameterEventsQoS())
|
||||
.allow_undeclared_parameters(true)
|
||||
.automatically_declare_parameters_from_overrides(true);
|
||||
|
||||
auto copied_options = non_default_options;
|
||||
EXPECT_EQ(non_default_options.parameter_overrides(), copied_options.parameter_overrides());
|
||||
EXPECT_EQ(non_default_options.use_global_arguments(), copied_options.use_global_arguments());
|
||||
EXPECT_EQ(non_default_options.enable_rosout(), copied_options.enable_rosout());
|
||||
EXPECT_EQ(non_default_options.use_intra_process_comms(),
|
||||
copied_options.use_intra_process_comms());
|
||||
EXPECT_EQ(non_default_options.enable_topic_statistics(),
|
||||
copied_options.enable_topic_statistics());
|
||||
EXPECT_EQ(non_default_options.start_parameter_services(),
|
||||
copied_options.start_parameter_services());
|
||||
EXPECT_EQ(non_default_options.enable_logger_service(), copied_options.enable_logger_service());
|
||||
EXPECT_EQ(non_default_options.start_parameter_event_publisher(),
|
||||
copied_options.start_parameter_event_publisher());
|
||||
EXPECT_EQ(non_default_options.clock_type(), copied_options.clock_type());
|
||||
EXPECT_EQ(non_default_options.clock_qos(), copied_options.clock_qos());
|
||||
EXPECT_EQ(non_default_options.use_clock_thread(), copied_options.use_clock_thread());
|
||||
EXPECT_EQ(non_default_options.parameter_event_qos(), copied_options.parameter_event_qos());
|
||||
EXPECT_EQ(non_default_options.rosout_qos(), copied_options.rosout_qos());
|
||||
EXPECT_EQ(non_default_options.allow_undeclared_parameters(),
|
||||
copied_options.allow_undeclared_parameters());
|
||||
EXPECT_EQ(non_default_options.automatically_declare_parameters_from_overrides(),
|
||||
copied_options.automatically_declare_parameters_from_overrides());
|
||||
}
|
||||
}
|
||||
|
||||
TEST(TestNodeOptions, append_parameter_override) {
|
||||
|
||||
@@ -124,10 +124,10 @@ TEST_F(TestServiceIntrospection, service_introspection_nominal)
|
||||
ASSERT_THAT(
|
||||
client_gid_arr,
|
||||
testing::Eq(event_map[ServiceEventInfo::REQUEST_SENT]->info.client_gid));
|
||||
// TODO(@fujitatomoya): Remove this if statement once other rmw implementations support test.
|
||||
// Only rmw_connextdds can pass this test requirement for now.
|
||||
// TODO(@fujitatomoya): Remove this if statement once rmw implementations support test.
|
||||
// rmw_cyclonedds_cpp does not pass this test requirement for now.
|
||||
// See more details for https://github.com/ros2/rmw/issues/357
|
||||
if (std::string(rmw_get_implementation_identifier()).find("rmw_connextdds") == 0) {
|
||||
if (std::string(rmw_get_implementation_identifier()).find("rmw_cyclonedds_cpp") != 0) {
|
||||
ASSERT_THAT(
|
||||
client_gid_arr,
|
||||
testing::Eq(event_map[ServiceEventInfo::REQUEST_RECEIVED]->info.client_gid));
|
||||
|
||||
@@ -65,7 +65,7 @@ TEST_F(TestSubscriptionOptions, topic_statistics_options_default_and_set) {
|
||||
EXPECT_EQ(options.topic_stats_options.state, rclcpp::TopicStatisticsState::NodeDefault);
|
||||
EXPECT_EQ(options.topic_stats_options.publish_topic, defaultPublishTopic);
|
||||
EXPECT_EQ(options.topic_stats_options.publish_period, 1s);
|
||||
EXPECT_EQ(options.topic_stats_options.qos, rclcpp::SystemDefaultsQoS());
|
||||
EXPECT_EQ(options.topic_stats_options.qos, rclcpp::SystemDefaultsQoS().keep_last(10));
|
||||
|
||||
options.topic_stats_options.state = rclcpp::TopicStatisticsState::Enable;
|
||||
options.topic_stats_options.publish_topic = "topic_statistics";
|
||||
|
||||
@@ -3,6 +3,14 @@ Changelog for package rclcpp_action
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
|
||||
29.2.0 (2024-11-25)
|
||||
-------------------
|
||||
|
||||
29.1.0 (2024-11-20)
|
||||
-------------------
|
||||
* Fix documentation typo in server_goal_handle.hpp (`#2669 <https://github.com/ros2/rclcpp/issues/2669>`_)
|
||||
* Contributors: YR
|
||||
|
||||
29.0.0 (2024-10-03)
|
||||
-------------------
|
||||
* Increase the timeout for the cppcheck on rclcpp_action. (`#2640 <https://github.com/ros2/rclcpp/issues/2640>`_)
|
||||
|
||||
@@ -43,7 +43,7 @@ class ServerGoalHandleBase
|
||||
{
|
||||
public:
|
||||
/// Indicate if client has requested this goal be cancelled.
|
||||
/// \return true if a cancelation request has been accepted for this goal.
|
||||
/// \return true if a cancellation request has been accepted for this goal.
|
||||
RCLCPP_ACTION_PUBLIC
|
||||
bool
|
||||
is_canceling() const;
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
<?xml-model href="http://download.ros.org/schema/package_format2.xsd" schematypens="http://www.w3.org/2001/XMLSchema"?>
|
||||
<package format="2">
|
||||
<name>rclcpp_action</name>
|
||||
<version>29.0.0</version>
|
||||
<version>29.2.0</version>
|
||||
<description>Adds action APIs for C++.</description>
|
||||
|
||||
<maintainer email="ivanpauno@ekumenlabs.com">Ivan Paunovic</maintainer>
|
||||
|
||||
@@ -2,6 +2,12 @@
|
||||
Changelog for package rclcpp_components
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
29.2.0 (2024-11-25)
|
||||
-------------------
|
||||
|
||||
29.1.0 (2024-11-20)
|
||||
-------------------
|
||||
|
||||
29.0.0 (2024-10-03)
|
||||
-------------------
|
||||
* Shutdown the context before context's destructor is invoked in tests (`#2633 <https://github.com/ros2/rclcpp/issues/2633>`_)
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
<?xml-model href="http://download.ros.org/schema/package_format2.xsd" schematypens="http://www.w3.org/2001/XMLSchema"?>
|
||||
<package format="2">
|
||||
<name>rclcpp_components</name>
|
||||
<version>29.0.0</version>
|
||||
<version>29.2.0</version>
|
||||
<description>Package containing tools for dynamically loadable components</description>
|
||||
|
||||
<maintainer email="ivanpauno@ekumenlabs.com">Ivan Paunovic</maintainer>
|
||||
|
||||
@@ -3,6 +3,14 @@ Changelog for package rclcpp_lifecycle
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
|
||||
29.2.0 (2024-11-25)
|
||||
-------------------
|
||||
|
||||
29.1.0 (2024-11-20)
|
||||
-------------------
|
||||
* Fix error message in rclcpp_lifecycle::State::reset() (`#2647 <https://github.com/ros2/rclcpp/issues/2647>`_)
|
||||
* Contributors: Christophe Bedard
|
||||
|
||||
29.0.0 (2024-10-03)
|
||||
-------------------
|
||||
* Shutdown the context before context's destructor is invoked in tests (`#2633 <https://github.com/ros2/rclcpp/issues/2633>`_)
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
<?xml-model href="http://download.ros.org/schema/package_format2.xsd" schematypens="http://www.w3.org/2001/XMLSchema"?>
|
||||
<package format="2">
|
||||
<name>rclcpp_lifecycle</name>
|
||||
<version>29.0.0</version>
|
||||
<version>29.2.0</version>
|
||||
<description>Package containing a prototype for lifecycle implementation</description>
|
||||
|
||||
<maintainer email="ivanpauno@ekumenlabs.com">Ivan Paunovic</maintainer>
|
||||
|
||||
@@ -167,7 +167,7 @@ State::reset() noexcept
|
||||
if (ret != RCL_RET_OK) {
|
||||
RCLCPP_ERROR(
|
||||
rclcpp::get_logger("rclcpp_lifecycle"),
|
||||
"rcl_lifecycle_transition_fini did not complete successfully, leaking memory");
|
||||
"rcl_lifecycle_state_fini did not complete successfully, leaking memory");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user