Skip to content

Commit 6352e86

Browse files
committed
Fixed executor yielding entities to wrong node
Also refactored some code to a sub-generator
1 parent dd86a13 commit 6352e86

File tree

1 file changed

+51
-41
lines changed

1 file changed

+51
-41
lines changed

rclpy/rclpy/executors.py

Lines changed: 51 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -252,6 +252,56 @@ def _can_execute(self, entity):
252252
"""
253253
return entity.callback_group.can_execute(entity) and not entity._executor_event
254254

255+
def _new_callbacks(self, nodes, wait_set):
256+
"""
257+
Yields brand new work to executor implementations.
258+
259+
:param nodes: nodes to yield work for
260+
:type nodes: list
261+
:param wait_set: wait set that has already been waited on
262+
:type wait_set: rclpy.wait_set.WaitSet
263+
:rtype: Generator[(callable, entity, :class:`rclpy.node.Node`)]
264+
"""
265+
yielded_work = False
266+
# Process ready entities one node at a time
267+
for node in nodes:
268+
for tmr in node.timers:
269+
if wait_set.is_ready(tmr.timer_pointer) and tmr.callback_group.can_execute(tmr):
270+
# TODO(Sloretz) Which rcl cancelled timer bug does this workaround?
271+
if not _rclpy.rclpy_is_timer_ready(tmr.timer_handle):
272+
continue
273+
handler = self._make_handler(tmr, self._take_timer, self._execute_timer)
274+
yielded_work = True
275+
yield handler, tmr, node
276+
277+
for sub in node.subscriptions:
278+
if (wait_set.is_ready(sub.subscription_pointer) and
279+
sub.callback_group.can_execute(sub)):
280+
handler = self._make_handler(
281+
sub, self._take_subscription, self._execute_subscription)
282+
yielded_work = True
283+
yield handler, sub, node
284+
285+
for gc in node.guards:
286+
if gc._executor_triggered and gc.callback_group.can_execute(gc):
287+
handler = self._make_handler(
288+
gc, self._take_guard_condition, self._execute_guard_condition)
289+
yielded_work = True
290+
yield handler, gc, node
291+
292+
for cli in node.clients:
293+
if wait_set.is_ready(cli.client_pointer) and cli.callback_group.can_execute(cli):
294+
handler = self._make_handler(cli, self._take_client, self._execute_client)
295+
yielded_work = True
296+
yield handler, cli, node
297+
298+
for srv in node.services:
299+
if wait_set.is_ready(srv.service_pointer) and srv.callback_group.can_execute(srv):
300+
handler = self._make_handler(srv, self._take_service, self._execute_service)
301+
yielded_work = True
302+
yield handler, srv, node
303+
return yielded_work
304+
255305
def wait_for_ready_callbacks(self, timeout_sec=None, nodes=None):
256306
"""
257307
Yield callbacks that are ready to be performed.
@@ -320,47 +370,7 @@ def wait_for_ready_callbacks(self, timeout_sec=None, nodes=None):
320370
for gc in [g for g in guards if wait_set.is_ready(g.guard_pointer)]:
321371
gc._executor_triggered = True
322372

323-
# Process ready entities one node at a time
324-
for node in nodes:
325-
for tmr in [t for t in timers if wait_set.is_ready(t.timer_pointer)]:
326-
# Check that a timer is ready to workaround rcl issue with cancelled timers
327-
if _rclpy.rclpy_is_timer_ready(tmr.timer_handle):
328-
if tmr == timeout_timer:
329-
continue
330-
elif tmr.callback_group.can_execute(tmr):
331-
handler = self._make_handler(
332-
tmr, self._take_timer, self._execute_timer)
333-
yielded_work = True
334-
yield handler, tmr, node
335-
336-
for sub in [s for s in subscriptions if wait_set.is_ready(
337-
s.subscription_pointer)]:
338-
if sub.callback_group.can_execute(sub):
339-
handler = self._make_handler(
340-
sub, self._take_subscription, self._execute_subscription)
341-
yielded_work = True
342-
yield handler, sub, node
343-
344-
for gc in [g for g in node.guards if g._executor_triggered]:
345-
if gc.callback_group.can_execute(gc):
346-
handler = self._make_handler(
347-
gc, self._take_guard_condition, self._execute_guard_condition)
348-
yielded_work = True
349-
yield handler, gc, node
350-
351-
for client in [c for c in clients if wait_set.is_ready(c.client_pointer)]:
352-
if client.callback_group.can_execute(client):
353-
handler = self._make_handler(
354-
client, self._take_client, self._execute_client)
355-
yielded_work = True
356-
yield handler, client, node
357-
358-
for srv in [s for s in services if wait_set.is_ready(s.service_pointer)]:
359-
if srv.callback_group.can_execute(srv):
360-
handler = self._make_handler(
361-
srv, self._take_service, self._execute_service)
362-
yielded_work = True
363-
yield handler, srv, node
373+
yielded_work = yield from self._new_callbacks(nodes, wait_set)
364374

365375
# Check timeout timer
366376
if (

0 commit comments

Comments
 (0)