Compare commits

...

17 Commits

Author SHA1 Message Date
Chris Lalancette
83c282a161 29.2.0 2024-11-25 14:38:16 +00:00
Chris Lalancette
226044022a Changelog.
Signed-off-by: Chris Lalancette <clalancette@gmail.com>
2024-11-25 14:38:05 +00:00
Tomoya Fujita
7e9ff5f4c7 accept custom allocator for LoanedMessage. (#2672)
* accept custom allocator for LoanedMessage.

Signed-off-by: Tomoya Fujita <Tomoya.Fujita@sony.com>

* move message allocator using directives to public.

Signed-off-by: Tomoya Fujita <Tomoya.Fujita@sony.com>

---------

Signed-off-by: Tomoya Fujita <Tomoya.Fujita@sony.com>
2024-11-21 13:50:59 -08:00
Chris Lalancette
64dd644469 29.1.0 2024-11-20 15:53:57 +00:00
Chris Lalancette
322b5f5d79 Changelog.
Signed-off-by: Chris Lalancette <clalancette@gmail.com>
2024-11-20 15:53:48 +00:00
Tomoya Fujita
e854bb29cd a couple of typo fixes in doc section for LoanedMessage. (#2676)
* rephrase doc section of LoanedMessage Class.

Signed-off-by: Tomoya Fujita <Tomoya.Fujita@sony.com>
Co-authored-by: Chris Lalancette <clalancette@gmail.com>
Co-authored-by: Christophe Bedard <bedard.christophe@gmail.com>
2024-11-19 07:14:45 -05:00
Christophe Bedard
88ebea94e9 Make sure callback_end tracepoint is triggered in AnyServiceCallback (#2670)
Signed-off-by: Christophe Bedard <christophe.bedard@apex.ai>
2024-11-11 13:39:38 -08:00
YR
1e6767ac13 Fix documentation typo in server_goal_handle.hpp (#2669)
Signed-off-by: Yurii Rovinskyi <yurii.rovinskyi.19@pnu.edu.ua>
2024-11-10 07:54:41 -08:00
Barry Xu
37e3688026 Correct the incorrect comments in generic_client.hpp (#2662)
Signed-off-by: Barry Xu <barry.xu@sony.com>
2024-11-05 08:07:02 -05:00
Romain DESILLE
9b654942f9 Fix NodeOptions assignment operator (#2656)
* Fix NodeOptions assignment operator

Also copy the enable_logger_service_ member during the assignment operation

* Add more checks for NodeOptions copy test

* Set non default values by avoiding the copy-assignement

Signed-off-by: Romain DESILLE <r.desille@gmail.com>
Co-authored-by: Christophe Bedard <bedard.christophe@gmail.com>
2024-10-30 07:45:19 -04:00
Tomoya Fujita
f12e3c69dc set QoS History KEEP_ALL explicitly for statistics publisher. (#2650)
* set QoS History KEEP_ALL explicitly for statistics publisher.

Signed-off-by: Tomoya Fujita <Tomoya.Fujita@sony.com>

* test_subscription_options adjustment.

Signed-off-by: Tomoya Fujita <Tomoya.Fujita@sony.com>

---------

Signed-off-by: Tomoya Fujita <Tomoya.Fujita@sony.com>
2024-10-19 14:21:20 -07:00
Chris Lalancette
bcc14755f9 Fix test_intra_process_manager.cpp with rmw_zenoh_cpp (#2653)
* Cleanup of test_intra_process_manager.cpp

In particular, make every pub and sub have to
pass in both a topic name and a QoS when they
are constructing mock pubs and subs for the
intra-process manager test.  This just makes it
easier to tell whether the pubs and subs should be
matched or not.

Signed-off-by: Chris Lalancette <clalancette@gmail.com>

* Make sure to check QoS compatibility in the intra_process_manager tests.

It turns out that the intra_process_manager will attempt to match
QoS between publishers and subscriptions as they are added to the IPM.
This is exactly correct, but the tests were not following the same
pattern.

Thus, when running these tests under Zenoh, the tests would fail
because more things would match than the tests were expecting.
Update the test to take the differences in QoS into account,
which fixes the test under rmw_zenoh_cpp (and keeps it working
for the existing DDS RMWs).

Signed-off-by: Chris Lalancette <clalancette@gmail.com>

* Added feedback

Signed-off-by: Alejandro Hernández Cordero <ahcorde@gmail.com>

---------

Signed-off-by: Chris Lalancette <clalancette@gmail.com>
Signed-off-by: Alejandro Hernández Cordero <ahcorde@gmail.com>
Co-authored-by: Alejandro Hernández Cordero <ahcorde@gmail.com>
2024-10-19 00:55:25 +02:00
Alejandro Hernández Cordero
4567b6ec80 Fixed test_events_executors in zenoh (#2643)
Signed-off-by: Alejandro Hernández Cordero <ahcorde@gmail.com>
2024-10-17 18:20:47 +02:00
Tomoya Fujita
0be8aa013e rmw_fastrtps supports service event gid uniqueness test. (#2638)
Signed-off-by: Tomoya Fujita <Tomoya.Fujita@sony.com>
2024-10-14 15:24:42 -04:00
Tomoya Fujita
41d3a27437 print warning if event callback is not supported instead of passing exception. (#2648)
Signed-off-by: Tomoya Fujita <Tomoya.Fujita@sony.com>
2024-10-09 15:22:46 +02:00
Christophe Bedard
c50f0c9c3d Fix error message in rclcpp_lifecycle::State::reset() (#2647)
The function that may not complete successfully is
`rcl_lifecycle_state_fini()`, not `rcl_lifecycle_transition_fini()`.

Signed-off-by: Christophe Bedard <christophe.bedard@apex.ai>
2024-10-09 12:26:26 +02:00
Barry Xu
f8aea8cc51 Implement callback support of async_send_request for service generic client (#2614)
Signed-off-by: Barry Xu <barry.xu@sony.com>
2024-10-04 12:12:00 +02:00
25 changed files with 484 additions and 127 deletions

View File

@@ -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>`_)

View File

@@ -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>();

View File

@@ -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,

View File

@@ -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))

View File

@@ -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;

View File

@@ -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>

View File

@@ -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)
{

View File

@@ -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_;

View File

@@ -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");
}
}

View File

@@ -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");
}
}

View File

@@ -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()

View File

@@ -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);
}

View File

@@ -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));
}

View File

@@ -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;

View File

@@ -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) {

View File

@@ -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));

View File

@@ -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";

View File

@@ -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>`_)

View File

@@ -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;

View File

@@ -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>

View File

@@ -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>`_)

View File

@@ -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>

View File

@@ -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>`_)

View File

@@ -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>

View File

@@ -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");
}
}