Skip to content

Instantly share code, notes, and snippets.

@nim65s
Last active May 12, 2020 20:15
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save nim65s/f42970a5531d2de744670a423e22559d to your computer and use it in GitHub Desktop.
Save nim65s/f42970a5531d2de744670a423e22559d to your computer and use it in GitHub Desktop.
"""
Snippet to show how to make a loop run at a given frequency without drift.
"""
import signal
import time
from abc import ABCMeta, abstractmethod
DT_DISPLAY = 0.04 # 25 fps
class Loop(metaclass=ABCMeta):
"""
Astract Class to allow users to execute self.loop at a given frequency
with a timer while self.run can do something else.
"""
def __init__(self, period):
self.period = period
signal.signal(signal.SIGALRM, self.loop)
signal.setitimer(signal.ITIMER_REAL, period, period)
self.run()
def stop(self):
signal.setitimer(signal.ITIMER_REAL, 0)
@abstractmethod
def run(self):
...
@abstractmethod
def loop(self, signum, frame):
...
class Viewer(Loop):
def __init__(self, *args, **kwargs):
self.t = 0
super().__init__(*args, **kwargs)
def loop(self, signum, frame):
self.t += self.period
print(f'robot.display(q_t({self.t}))')
if self.t >= 5:
self.stop()
def run(self):
# we don't actually need anything here, just sleep.
try:
time.sleep(1e9)
except KeyboardInterrupt:
pass
def stop(self):
super().stop()
raise KeyboardInterrupt # our self.run is waiting for this.
if __name__ == '__main__':
Viewer(DT_DISPLAY)
@nim65s
Copy link
Author

nim65s commented May 12, 2020

$ /usr/bin/time python loop.py
[…]
0.05user 0.01system 0:05.06elapsed 1%CPU (0avgtext+0avgdata 9560maxresident)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment