Skip to content

Commit 14e009e

Browse files
committed
Updates
Signed-off-by: Michael Carroll <[email protected]>
1 parent 9950fb9 commit 14e009e

File tree

8 files changed

+115
-111
lines changed

8 files changed

+115
-111
lines changed

rclcpp/include/rclcpp/callback_group.hpp

-4
Original file line numberDiff line numberDiff line change
@@ -152,10 +152,6 @@ class CallbackGroup
152152
bool
153153
has_valid_node();
154154

155-
RCLCPP_PUBLIC
156-
bool
157-
has_valid_node();
158-
159155
RCLCPP_PUBLIC
160156
std::atomic_bool &
161157
can_be_taken_from();

rclcpp/include/rclcpp/executor.hpp

+6
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@
3030

3131
#include "rcl/guard_condition.h"
3232
#include "rcl/wait.h"
33+
#include "rclcpp/executors/executor_notify_waitable.hpp"
3334
#include "rcpputils/scope_exit.hpp"
3435

3536
#include "rclcpp/context.hpp"
@@ -484,6 +485,10 @@ class Executor
484485
static void
485486
execute_client(rclcpp::ClientBase::SharedPtr client);
486487

488+
RCLCPP_PUBLIC
489+
void
490+
collect_entities();
491+
487492
/// Block until more work becomes avilable or timeout is reached.
488493
/**
489494
* Builds a set of waitable entities, which are passed to the middleware.
@@ -541,6 +546,7 @@ class Executor
541546
virtual void
542547
spin_once_impl(std::chrono::nanoseconds timeout);
543548

549+
std::shared_ptr<rclcpp::executors::ExecutorNotifyWaitable> notify_waitable_;
544550
rclcpp::executors::ExecutorEntitiesCollector collector_;
545551
rclcpp::executors::ExecutorEntitiesCollection current_collection_;
546552

rclcpp/include/rclcpp/wait_set_template.hpp

+1
Original file line numberDiff line numberDiff line change
@@ -661,6 +661,7 @@ class WaitSetTemplate final : private SynchronizationPolicy, private StoragePoli
661661
this->storage_acquire_ownerships();
662662
RCPPUTILS_SCOPE_EXIT({this->storage_release_ownerships();});
663663

664+
664665
// this method comes from the SynchronizationPolicy
665666
return this->template sync_wait<WaitResult<WaitSetTemplate>>(
666667
// pass along the time_to_wait duration as nanoseconds

rclcpp/src/rclcpp/executor.cpp

+104-97
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@
2323

2424
#include "rcl/allocator.h"
2525
#include "rcl/error_handling.h"
26+
#include "rclcpp/executors/executor_notify_waitable.hpp"
2627
#include "rclcpp/subscription_wait_set_mask.hpp"
2728
#include "rcpputils/scope_exit.hpp"
2829

@@ -46,6 +47,11 @@ Executor::Executor(const rclcpp::ExecutorOptions & options)
4647
: spinning(false),
4748
interrupt_guard_condition_(options.context),
4849
shutdown_guard_condition_(std::make_shared<rclcpp::GuardCondition>(options.context)),
50+
notify_waitable_(std::make_shared<rclcpp::executors::ExecutorNotifyWaitable>(
51+
[this]() {
52+
this->collect_entities();
53+
})),
54+
collector_(notify_waitable_),
4955
wait_set_(std::make_shared<rclcpp::WaitSet>())
5056
{
5157
// Store the context for later use.
@@ -59,39 +65,45 @@ Executor::Executor(const rclcpp::ExecutorOptions & options)
5965
}
6066
});
6167

62-
this->collector_.get_executor_notify_waitable()->add_guard_condition(
63-
&interrupt_guard_condition_);
64-
this->collector_.get_executor_notify_waitable()->add_guard_condition(
65-
shutdown_guard_condition_.get());
68+
notify_waitable_->add_guard_condition(&interrupt_guard_condition_);
69+
notify_waitable_->add_guard_condition(shutdown_guard_condition_.get());
6670
}
6771

6872
Executor::~Executor()
6973
{
70-
current_collection_.update_timers({},
71-
[this](auto timer){wait_set_->add_timer(timer);},
72-
[this](auto timer){wait_set_->remove_timer(timer);});
73-
74-
current_collection_.update_subscriptions({},
75-
[this](auto subscription){
76-
wait_set_->add_subscription(subscription, kDefaultSubscriptionMask);},
77-
[this](auto subscription){
78-
wait_set_->remove_subscription(subscription, kDefaultSubscriptionMask);});
74+
current_collection_.timers.update(
75+
{},
76+
[this](auto timer) {wait_set_->add_timer(timer);},
77+
[this](auto timer) {wait_set_->remove_timer(timer);});
78+
79+
current_collection_.subscriptions.update(
80+
{},
81+
[this](auto subscription) {
82+
wait_set_->add_subscription(subscription, kDefaultSubscriptionMask);
83+
},
84+
[this](auto subscription) {
85+
wait_set_->remove_subscription(subscription, kDefaultSubscriptionMask);
86+
});
7987

80-
current_collection_.update_clients({},
81-
[this](auto client){wait_set_->add_client(client);},
82-
[this](auto client){wait_set_->remove_client(client);});
88+
current_collection_.clients.update(
89+
{},
90+
[this](auto client) {wait_set_->add_client(client);},
91+
[this](auto client) {wait_set_->remove_client(client);});
8392

84-
current_collection_.update_services({},
85-
[this](auto service){wait_set_->add_service(service);},
86-
[this](auto service){wait_set_->remove_service(service);});
93+
current_collection_.services.update(
94+
{},
95+
[this](auto service) {wait_set_->add_service(service);},
96+
[this](auto service) {wait_set_->remove_service(service);});
8797

88-
current_collection_.update_guard_conditions({},
89-
[this](auto guard_condition){wait_set_->add_guard_condition(guard_condition);},
90-
[this](auto guard_condition){wait_set_->remove_guard_condition(guard_condition);});
98+
current_collection_.guard_conditions.update(
99+
{},
100+
[this](auto guard_condition) {wait_set_->add_guard_condition(guard_condition);},
101+
[this](auto guard_condition) {wait_set_->remove_guard_condition(guard_condition);});
91102

92-
current_collection_.update_waitables({},
93-
[this](auto waitable){wait_set_->add_waitable(waitable);},
94-
[this](auto waitable){wait_set_->remove_waitable(waitable);});
103+
current_collection_.waitables.update(
104+
{},
105+
[this](auto waitable) {wait_set_->add_waitable(waitable);},
106+
[this](auto waitable) {wait_set_->remove_waitable(waitable);});
95107

96108
// Remove shutdown callback handle registered to Context
97109
if (!context_->remove_on_shutdown_callback(shutdown_callback_handle_)) {
@@ -129,15 +141,14 @@ Executor::add_callback_group(
129141
(void) node_ptr;
130142
this->collector_.add_callback_group(group_ptr);
131143

132-
if (notify)
133-
{
144+
if (notify) {
134145
// Interrupt waiting to handle removed callback group
135146
try {
136147
interrupt_guard_condition_.trigger();
137148
} catch (const rclcpp::exceptions::RCLError & ex) {
138149
throw std::runtime_error(
139-
std::string(
140-
"Failed to trigger guard condition on callback group add: ") + ex.what());
150+
std::string(
151+
"Failed to trigger guard condition on callback group add: ") + ex.what());
141152
}
142153
}
143154
}
@@ -146,15 +157,14 @@ void
146157
Executor::add_node(rclcpp::node_interfaces::NodeBaseInterface::SharedPtr node_ptr, bool notify)
147158
{
148159
this->collector_.add_node(node_ptr);
149-
if (notify)
150-
{
160+
if (notify) {
151161
// Interrupt waiting to handle removed callback group
152162
try {
153163
interrupt_guard_condition_.trigger();
154164
} catch (const rclcpp::exceptions::RCLError & ex) {
155165
throw std::runtime_error(
156-
std::string(
157-
"Failed to trigger guard condition on callback group remove: ") + ex.what());
166+
std::string(
167+
"Failed to trigger guard condition on callback group remove: ") + ex.what());
158168
}
159169
}
160170
}
@@ -166,15 +176,14 @@ Executor::remove_callback_group(
166176
{
167177
this->collector_.remove_callback_group(group_ptr);
168178

169-
if (notify)
170-
{
179+
if (notify) {
171180
// Interrupt waiting to handle removed callback group
172181
try {
173182
interrupt_guard_condition_.trigger();
174183
} catch (const rclcpp::exceptions::RCLError & ex) {
175184
throw std::runtime_error(
176-
std::string(
177-
"Failed to trigger guard condition on callback group remove: ") + ex.what());
185+
std::string(
186+
"Failed to trigger guard condition on callback group remove: ") + ex.what());
178187
}
179188
}
180189
}
@@ -183,34 +192,21 @@ void
183192
Executor::add_node(std::shared_ptr<rclcpp::Node> node_ptr, bool notify)
184193
{
185194
this->add_node(node_ptr->get_node_base_interface(), notify);
186-
187-
if (notify)
188-
{
189-
// Interrupt waiting to handle removed callback group
190-
try {
191-
interrupt_guard_condition_.trigger();
192-
} catch (const rclcpp::exceptions::RCLError & ex) {
193-
throw std::runtime_error(
194-
std::string(
195-
"Failed to trigger guard condition on node add: ") + ex.what());
196-
}
197-
}
198195
}
199196

200197
void
201198
Executor::remove_node(rclcpp::node_interfaces::NodeBaseInterface::SharedPtr node_ptr, bool notify)
202199
{
203200
this->collector_.remove_node(node_ptr);
204201

205-
if (notify)
206-
{
202+
if (notify) {
207203
// Interrupt waiting to handle removed callback group
208204
try {
209205
interrupt_guard_condition_.trigger();
210206
} catch (const rclcpp::exceptions::RCLError & ex) {
211207
throw std::runtime_error(
212-
std::string(
213-
"Failed to trigger guard condition on callback group add: ") + ex.what());
208+
std::string(
209+
"Failed to trigger guard condition on callback group add: ") + ex.what());
214210
}
215211
}
216212
}
@@ -356,16 +352,10 @@ Executor::execute_any_executable(AnyExecutable & any_exec)
356352
if (any_exec.waitable) {
357353
any_exec.waitable->execute(any_exec.data);
358354
}
355+
359356
// Reset the callback_group, regardless of type
360-
any_exec.callback_group->can_be_taken_from().store(true);
361-
// Wake the wait, because it may need to be recalculated or work that
362-
// was previously blocked is now available.
363-
try {
364-
interrupt_guard_condition_.trigger();
365-
} catch (const rclcpp::exceptions::RCLError & ex) {
366-
throw std::runtime_error(
367-
std::string(
368-
"Failed to trigger guard condition from execute_any_executable: ") + ex.what());
357+
if (any_exec.callback_group) {
358+
any_exec.callback_group->can_be_taken_from().store(true);
369359
}
370360
}
371361

@@ -506,47 +496,65 @@ Executor::execute_client(
506496
}
507497

508498
void
509-
Executor::wait_for_work(std::chrono::nanoseconds timeout)
499+
Executor::collect_entities()
510500
{
511-
TRACEPOINT(rclcpp_executor_wait_for_work, timeout.count());
512-
{
513-
std::lock_guard<std::mutex> guard(mutex_);
514-
515-
rclcpp::executors::ExecutorEntitiesCollection collection;
516-
auto callback_groups = this->collector_.get_all_callback_groups();
517-
rclcpp::executors::build_entities_collection(callback_groups, collection);
518-
519-
current_collection_.update_timers(collection.timers,
520-
[this](auto timer){wait_set_->add_timer(timer);},
521-
[this](auto timer){wait_set_->remove_timer(timer);});
522-
523-
current_collection_.update_subscriptions(collection.subscriptions,
524-
[this](auto subscription){
525-
wait_set_->add_subscription(subscription, kDefaultSubscriptionMask);},
526-
[this](auto subscription){
527-
wait_set_->remove_subscription(subscription, kDefaultSubscriptionMask);});
528-
529-
current_collection_.update_clients(collection.clients,
530-
[this](auto client){wait_set_->add_client(client);},
531-
[this](auto client){wait_set_->remove_client(client);});
501+
std::lock_guard<std::mutex> guard(mutex_);
502+
503+
rclcpp::executors::ExecutorEntitiesCollection collection;
504+
this->collector_.update_collections();
505+
auto callback_groups = this->collector_.get_all_callback_groups();
506+
rclcpp::executors::build_entities_collection(callback_groups, collection);
507+
508+
auto notify_waitable = std::static_pointer_cast<rclcpp::Waitable>(notify_waitable_);
509+
collection.waitables.insert({notify_waitable.get(), {notify_waitable, {}}});
510+
511+
current_collection_.timers.update(
512+
collection.timers,
513+
[this](auto timer) {wait_set_->add_timer(timer);},
514+
[this](auto timer) {wait_set_->remove_timer(timer);});
515+
516+
current_collection_.subscriptions.update(
517+
collection.subscriptions,
518+
[this](auto subscription) {
519+
wait_set_->add_subscription(subscription, kDefaultSubscriptionMask);
520+
},
521+
[this](auto subscription) {
522+
wait_set_->remove_subscription(subscription, kDefaultSubscriptionMask);
523+
});
532524

533-
current_collection_.update_services(collection.services,
534-
[this](auto service){wait_set_->add_service(service);},
535-
[this](auto service){wait_set_->remove_service(service);});
525+
current_collection_.clients.update(
526+
collection.clients,
527+
[this](auto client) {wait_set_->add_client(client);},
528+
[this](auto client) {wait_set_->remove_client(client);});
529+
530+
current_collection_.services.update(
531+
collection.services,
532+
[this](auto service) {wait_set_->add_service(service);},
533+
[this](auto service) {wait_set_->remove_service(service);});
534+
535+
current_collection_.guard_conditions.update(
536+
collection.guard_conditions,
537+
[this](auto guard_condition) {wait_set_->add_guard_condition(guard_condition);},
538+
[this](auto guard_condition) {wait_set_->remove_guard_condition(guard_condition);});
539+
540+
current_collection_.waitables.update(
541+
collection.waitables,
542+
[this](auto waitable) {wait_set_->add_waitable(waitable);},
543+
[this](auto waitable) {wait_set_->remove_waitable(waitable);});
544+
}
536545

537-
current_collection_.update_guard_conditions(collection.guard_conditions,
538-
[this](auto guard_condition){wait_set_->add_guard_condition(guard_condition);},
539-
[this](auto guard_condition){wait_set_->remove_guard_condition(guard_condition);});
546+
void
547+
Executor::wait_for_work(std::chrono::nanoseconds timeout)
548+
{
549+
TRACEPOINT(rclcpp_executor_wait_for_work, timeout.count());
540550

541-
current_collection_.update_waitables(collection.waitables,
542-
[this](auto waitable){wait_set_->add_waitable(waitable);},
543-
[this](auto waitable){wait_set_->remove_waitable(waitable);});
551+
if (current_collection_.empty()) {
552+
this->collect_entities();
544553
}
545554

546555
auto wait_result = wait_set_->wait(timeout);
547556

548-
if (wait_result.kind() == WaitResultKind::Empty)
549-
{
557+
if (wait_result.kind() == WaitResultKind::Empty) {
550558
RCUTILS_LOG_WARN_NAMED(
551559
"rclcpp",
552560
"empty wait set received in wait(). This should never happen.");
@@ -562,8 +570,7 @@ Executor::get_next_ready_executable(AnyExecutable & any_executable)
562570
TRACEPOINT(rclcpp_executor_get_next_ready);
563571
std::lock_guard<std::mutex> guard{mutex_};
564572

565-
if (ready_executables_.size() == 0)
566-
{
573+
if (ready_executables_.size() == 0) {
567574
return false;
568575
}
569576

rclcpp/src/rclcpp/executors/executor_entities_collection.cpp

+1
Original file line numberDiff line numberDiff line change
@@ -121,6 +121,7 @@ void check_ready(
121121
exec.callback_group = callback_group;
122122
if (fill_executable(exec, entity)) {
123123
executables.push_back(exec);
124+
} else {
124125
}
125126
}
126127
}

rclcpp/src/rclcpp/executors/executor_notify_waitable.cpp

+2
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,7 @@ ExecutorNotifyWaitable::add_to_wait_set(rcl_wait_set_t * wait_set)
4848
bool
4949
ExecutorNotifyWaitable::is_ready(rcl_wait_set_t * wait_set)
5050
{
51+
std::cout << "ExecutorNotifyWaitable::is_ready" << std::endl;
5152
std::lock_guard<std::mutex> lock(guard_condition_mutex_);
5253
for (size_t ii = 0; ii < wait_set->size_of_guard_conditions; ++ii) {
5354
auto rcl_guard_condition = wait_set->guard_conditions[ii];
@@ -68,6 +69,7 @@ ExecutorNotifyWaitable::is_ready(rcl_wait_set_t * wait_set)
6869
void
6970
ExecutorNotifyWaitable::execute(std::shared_ptr<void> & data)
7071
{
72+
std::cout << "ExecutorNotifyWaitable::execute" << std::endl;
7173
(void) data;
7274
this->execute_callback_();
7375
}

0 commit comments

Comments
 (0)