pyrcf.utils.time_utils ====================== .. py:module:: pyrcf.utils.time_utils .. autoapi-nested-parse:: Utilities for timer and rate-related functionalities. Classes ------- .. autoapisummary:: pyrcf.utils.time_utils.ClockBase pyrcf.utils.time_utils.PythonEpochClock pyrcf.utils.time_utils.PythonPerfClock pyrcf.utils.time_utils.RateLimiter pyrcf.utils.time_utils.RateTrigger Module Contents --------------- .. py:class:: ClockBase Bases: :py:obj:`abc.ABC` Base class for any Clock implementation for pyrcf control loop and components. .. py:method:: get_time() -> float :abstractmethod: Get the latest time from this clock. :raises NotImplementedError: Raised if this method is not implemented by the child class. :returns: the current time in seconds. :rtype: float .. py:class:: PythonEpochClock Bases: :py:obj:`ClockBase` ClockBase implementation to query system time using `time.time()`. .. py:method:: get_time() -> float Get the latest time from this clock. :raises NotImplementedError: Raised if this method is not implemented by the child class. :returns: the current time in seconds. :rtype: float .. py:class:: PythonPerfClock Bases: :py:obj:`ClockBase` ClockBase implementation to query counter using `time.perf_counter()`. Only meaningful when comparing values from other `time.perf_counter()` calls. .. py:method:: get_time() -> float Get the latest time from this clock. :raises NotImplementedError: Raised if this method is not implemented by the child class. :returns: the current time in seconds. :rtype: float .. py:class:: RateLimiter(frequency: float, name: str = 'rate limiter', warn: bool = False, clock: ClockBase = PythonPerfClock()) Modified from https://github.com/upkie/loop-rate-limiters/blob/main/loop_rate_limiters/rate_limiter.py. Original License terms below: Regulate the frequency between calls to the same instruction. This rate limniter is meant to be used in e.g. a loop or callback function. It is, in essence, the same as rospy.Rate_. It assumes Python's performance counter never jumps backward nor forward, so that it does not handle such cases contrary to rospy.Rate_. .. _rospy.Rate: https://github.com/ros/ros_comm/blob/noetic-devel/clients/rospy/src/rospy/timer.py .. attribute:: name Human-readable name used for logging. .. attribute:: warn If set (default), warn when the time between two calls exceeded the rate clock. # # Copyright 2022 Stéphane Caron # Copyright 2023 Inria # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. .. py:attribute:: __period :type: float .. py:attribute:: __slack :type: float .. py:attribute:: __next_tick :type: float .. py:attribute:: __freq :type: float .. py:attribute:: name :type: str .. py:attribute:: warn :type: bool .. py:method:: set_frequency(frequency: float) .. py:method:: change_clock(clock: ClockBase) .. py:property:: clock :type: ClockBase The clock used by this class. Use `get_time()` on this attribute to get current time in seconds. :returns: The clock object used by this class. :rtype: ClockBase .. py:property:: dt :type: float Desired period between two calls to :func:`sleep`, in seconds. .. py:property:: next_tick :type: float Time of next clock tick. .. py:property:: period :type: float Desired period between two calls to :func:`sleep`, in seconds. .. py:property:: frequency :type: float Desired frequency between two calls to :func:`sleep`, in seconds. .. py:property:: slack :type: float Slack duration computed at the last call to :func:`sleep`. This duration is in seconds. .. py:method:: remaining() -> float Get the time remaining until the next expected clock tick. :returns: Time remaining, in seconds, until the next expected clock tick. .. py:method:: sleep() Sleep for the duration required to regulate inter-call frequency. .. py:class:: RateTrigger(rate: float, clock: ClockBase = PythonPerfClock()) Can be used to execute something at a specific rate. Checking the `.triggered()` method of this class will return True or False depending on whether the specified rate has reached. NOTE: Warning: When using this with RateLimiter in the same loop, try to keep the rate of this class a factor of the rate of the RateLimiter object. Otherwise, the RateTrigger will not be able to keep the required rate (because RateLimiter enforces a sleep). Make sure to use same clock as well. .. py:attribute:: __period .. py:attribute:: __next_tick :value: None .. py:method:: change_clock(clock: ClockBase) .. py:property:: clock :type: ClockBase The clock used by this class. Use `get_time()` on this attribute to get current time in seconds. :returns: The clock object used by this class. :rtype: ClockBase .. py:property:: dt :type: float Desired period between two calls to :func:`sleep`, in seconds. .. py:property:: next_tick :type: float Time of next clock tick. .. py:property:: period :type: float Desired period between two calls to :func:`sleep`, in seconds. .. py:method:: triggered() -> bool Check if the specified rate has been triggered. .. py:property:: has_triggered :type: bool Attribute to check if the specified rate has been triggered. .. py:method:: __call__() -> bool Calling this class object directly will check if the specified rate has been triggered.