Merge branch 'cycle_precision' into develop

This commit is contained in:
2021-11-03 20:15:01 +01:00
4 changed files with 25 additions and 31 deletions

View File

@@ -22,7 +22,7 @@ __author__ = "Sven Sager <akira@revpimodio.org>"
__copyright__ = "Copyright (C) 2020 Sven Sager" __copyright__ = "Copyright (C) 2020 Sven Sager"
__license__ = "LGPLv3" __license__ = "LGPLv3"
__name__ = "revpimodio2" __name__ = "revpimodio2"
__version__ = "2.5.8" __version__ = "2.5.8c"
# Global package values # Global package values
OFF = 0 OFF = 0

View File

@@ -365,7 +365,7 @@ class ProcimgWriter(Thread):
""" """
__slots__ = "__dict_delay", "__eventth", "_eventqth", "__eventwork", \ __slots__ = "__dict_delay", "__eventth", "_eventqth", "__eventwork", \
"_adjwait", "_eventq", "_modio", \ "_eventq", "_modio", \
"_refresh", "_work", "daemon", "lck_refresh", "newdata" "_refresh", "_work", "daemon", "lck_refresh", "newdata"
def __init__(self, parentmodio): def __init__(self, parentmodio):
@@ -375,7 +375,6 @@ class ProcimgWriter(Thread):
self.__eventth = Thread(target=self.__exec_th) self.__eventth = Thread(target=self.__exec_th)
self._eventqth = queue.Queue() self._eventqth = queue.Queue()
self.__eventwork = False self.__eventwork = False
self._adjwait = 0
self._eventq = queue.Queue() self._eventq = queue.Queue()
self._modio = parentmodio self._modio = parentmodio
self._refresh = 0.05 self._refresh = 0.05
@@ -512,22 +511,22 @@ class ProcimgWriter(Thread):
def run(self): def run(self):
"""Startet die automatische Prozessabbildsynchronisierung.""" """Startet die automatische Prozessabbildsynchronisierung."""
fh = self._modio._create_myfh() fh = self._modio._create_myfh()
self._adjwait = self._refresh
mrk_delay = self._refresh
mrk_warn = True mrk_warn = True
mrk_dt = default_timer()
bytesbuff = bytearray(self._modio._length) bytesbuff = bytearray(self._modio._length)
while not self._work.is_set():
ot = mrk_dt
# Lockobjekt holen und Fehler werfen, wenn nicht schnell genug while not self._work.is_set():
if not self.lck_refresh.acquire(timeout=self._adjwait): ot = default_timer()
# At this point, we slept and have the rest of delay from last cycle
if not self.lck_refresh.acquire(timeout=mrk_delay):
warnings.warn( warnings.warn(
"cycle time of {0} ms exceeded during executing function" "cycle time of {0} ms exceeded in your cycle function"
"".format(int(self._refresh * 1000)), "".format(int(self._refresh * 1000)),
RuntimeWarning RuntimeWarning
) )
mrk_delay = self._refresh
# Nur durch cycleloop erreichbar - keine verzögerten Events # Nur durch cycleloop erreichbar - keine verzögerten Events
continue continue
@@ -609,22 +608,18 @@ class ProcimgWriter(Thread):
self._eventq.put(tup_fire, False) self._eventq.put(tup_fire, False)
del self.__dict_delay[tup_fire] del self.__dict_delay[tup_fire]
# Sleep and not .wait (.wait uses system clock) mrk_delay = default_timer() % self._refresh
sleep(self._adjwait) # Second default_timer call include calculation time from above
if default_timer() - ot > self._refresh:
# Wartezeit anpassen um echte self._refresh zu erreichen warnings.warn(
mrk_dt = default_timer() "cycle time of {0} ms exceeded - can not hold cycle time!"
if mrk_dt - ot >= self._refresh: "".format(int(self._refresh * 1000)),
self._adjwait -= 0.001 RuntimeWarning
if self._adjwait < 0: )
warnings.warn( mrk_delay = 0.0
"cycle time of {0} ms exceeded several times - can not"
" hold cycle time!".format(int(self._refresh * 1000)),
RuntimeWarning
)
self._adjwait = 0
else: else:
self._adjwait += 0.001 # Sleep and not .wait (.wait uses system clock)
sleep(self._refresh - mrk_delay)
# Alle am Ende erneut aufwecken # Alle am Ende erneut aufwecken
self._collect_events(False) self._collect_events(False)
@@ -639,9 +634,7 @@ class ProcimgWriter(Thread):
"""Setzt die Zykluszeit in Millisekunden. """Setzt die Zykluszeit in Millisekunden.
@param value <class 'int'> Millisekunden""" @param value <class 'int'> Millisekunden"""
if type(value) == int and 5 <= value <= 2000: if type(value) == int and 5 <= value <= 2000:
waitdiff = self._refresh - self._adjwait
self._refresh = value / 1000 self._refresh = value / 1000
self._adjwait = 0 if waitdiff < 0 else self._refresh - waitdiff
else: else:
raise ValueError( raise ValueError(
"refresh time must be 5 to 2000 milliseconds" "refresh time must be 5 to 2000 milliseconds"

View File

@@ -767,10 +767,10 @@ class RevPiModIO(object):
# Zykluszeit übernehmen # Zykluszeit übernehmen
old_cycletime = self._imgwriter.refresh old_cycletime = self._imgwriter.refresh
if not cycletime == self._imgwriter.refresh: if not cycletime == self._imgwriter.refresh:
# Set new cycle time and wait one imgwriter cycle to sync fist cycle
self._imgwriter.refresh = cycletime self._imgwriter.refresh = cycletime
# Zeitänderung in _imgwriter neuladen
self._imgwriter.newdata.clear() self._imgwriter.newdata.clear()
self._imgwriter.newdata.wait(self._imgwriter._refresh)
# Benutzerevent # Benutzerevent
self.exitsignal.clear() self.exitsignal.clear()
@@ -781,6 +781,7 @@ class RevPiModIO(object):
cycleinfo = helpermodule.Cycletools(self._imgwriter.refresh, self) cycleinfo = helpermodule.Cycletools(self._imgwriter.refresh, self)
e = None # Exception e = None # Exception
ec = None # Return value of cycle_function ec = None # Return value of cycle_function
self._imgwriter.newdata.clear()
try: try:
while ec is None and not cycleinfo.last: while ec is None and not cycleinfo.last:
# Auf neue Daten warten und nur ausführen wenn set() # Auf neue Daten warten und nur ausführen wenn set()

View File

@@ -17,7 +17,7 @@ setup(
license="LGPLv3", license="LGPLv3",
name="revpimodio2", name="revpimodio2",
version="2.5.8", version="2.5.8c",
packages=["revpimodio2"], packages=["revpimodio2"],
python_requires="~=3.2", python_requires="~=3.2",