Skip to content

Commit

Permalink
time_until_next_call returns max if timer is canceled. (ros2#910)
Browse files Browse the repository at this point in the history
* time_until_next_call returns None if timer is canceled.

Signed-off-by: Tomoya Fujita <Tomoya.Fujita@sony.com>
Co-Authored-By: Ivan Santiago Paunovic <ivanpauno@ekumenlabs.com>
Signed-off-by: Alex Thiel <apocthiel@gmail.com>
  • Loading branch information
2 people authored and apockill committed Mar 16, 2022
1 parent d4d141c commit 00b9cf5
Show file tree
Hide file tree
Showing 3 changed files with 43 additions and 7 deletions.
6 changes: 4 additions & 2 deletions rclpy/src/rclpy/timer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -105,11 +105,13 @@ void Timer::change_timer_period(int64_t period_nsec)
}
}

int64_t Timer::time_until_next_call()
std::optional<int64_t> Timer::time_until_next_call()
{
int64_t remaining_time;
rcl_ret_t ret = rcl_timer_get_time_until_next_call(rcl_timer_.get(), &remaining_time);
if (ret != RCL_RET_OK) {
if (ret == RCL_RET_TIMER_CANCELED) {
return std::nullopt;
} else if (ret != RCL_RET_OK) {
throw RCLError("failed to get time until next timer call");
}

Expand Down
6 changes: 4 additions & 2 deletions rclpy/src/rclpy/timer.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
#define RCLPY__TIMER_HPP_

#include <pybind11/pybind11.h>
#include <pybind11/stl.h>

#include <rcl/timer.h>

Expand Down Expand Up @@ -87,9 +88,10 @@ class Timer : public Destroyable, public std::enable_shared_from_this<Timer>
*
* Raises RCLError there is an rcl error
*
* \return the time until next call in nanoseconds
* \return the time until next call in nanoseconds.
* std::nullopt if the timer is canceled.
*/
int64_t time_until_next_call();
std::optional<int64_t> time_until_next_call();

/// Get the time since the timer has been called
/**
Expand Down
38 changes: 35 additions & 3 deletions rclpy/test/test_timer.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@

import pytest
import rclpy
from rclpy.constants import S_TO_NS
from rclpy.executors import SingleThreadedExecutor


Expand Down Expand Up @@ -49,7 +50,7 @@ def test_zero_callback(period):
executor = SingleThreadedExecutor(context=context)
try:
executor.add_node(node)
# The first spin_once() takes long enough for 1ms timer tests to fail
# The first spin_once() takes long enough for 1ms timer tests to fail
executor.spin_once(timeout_sec=0)

callbacks = []
Expand Down Expand Up @@ -78,7 +79,7 @@ def test_number_callbacks(period):
executor = SingleThreadedExecutor(context=context)
try:
executor.add_node(node)
# The first spin_once() takes long enough for 1ms timer tests to fail
# The first spin_once() takes long enough for 1ms timer tests to fail
executor.spin_once(timeout_sec=0)

callbacks = []
Expand Down Expand Up @@ -110,7 +111,7 @@ def test_cancel_reset(period):
executor = SingleThreadedExecutor(context=context)
try:
executor.add_node(node)
# The first spin_once() takes long enough for 1ms timer tests to fail
# The first spin_once() takes long enough for 1ms timer tests to fail
executor.spin_once(timeout_sec=0)

callbacks = []
Expand Down Expand Up @@ -148,3 +149,34 @@ def test_cancel_reset(period):
node.destroy_node()
finally:
rclpy.shutdown(context=context)


def test_time_until_next_call():
node = None
executor = None
timer = None
context = rclpy.context.Context()
rclpy.init(context=context)
try:
node = rclpy.create_node('test_time_until_next_call', context=context)
executor = SingleThreadedExecutor(context=context)
executor.add_node(node)
executor.spin_once(timeout_sec=0)
timer = node.create_timer(1, lambda: None)
assert not timer.is_canceled()
executor.spin_once(0.1)
assert timer.time_until_next_call() <= (1 * S_TO_NS)
timer.reset()
assert not timer.is_canceled()
assert timer.time_until_next_call() <= (1 * S_TO_NS)
timer.cancel()
assert timer.is_canceled()
assert timer.time_until_next_call() is None
finally:
if timer is not None:
node.destroy_timer(timer)
if executor is not None:
executor.shutdown()
if node is not None:
node.destroy_node()
rclpy.shutdown(context=context)

0 comments on commit 00b9cf5

Please sign in to comment.