@@ -91,6 +91,9 @@ def __lt__(self, other) -> bool:
9191 def __bool__ (self ) -> bool :
9292 return True
9393
94+ def __repr__ (self ) -> str :
95+ return f"{{func={ self .func .__name__ } , _periodUs={ self ._periodUs } , expirationUs={ self .expirationUs } }}"
96+
9497
9598class _OrderedList :
9699 def __init__ (self ) -> None :
@@ -119,7 +122,7 @@ def __iter__(self) -> Iterable[Any]:
119122 def __contains__ (self , item ) -> bool :
120123 return item in self ._data
121124
122- def __str__ (self ) -> str :
125+ def __repr__ (self ) -> str :
123126 return str (sorted (self ._data ))
124127
125128
@@ -155,7 +158,6 @@ def __init__(self, period: wpimath.units.seconds = kDefaultPeriod) -> None:
155158 self .addPeriodic (self ._loopFunc , period = self ._periodS )
156159
157160 self ._notifier , status = initializeNotifier ()
158- print (f"{ self ._notifier } , { status } = initializeNotifier()" )
159161 if status != 0 :
160162 raise RuntimeError (
161163 f"initializeNotifier() returned { self ._notifier } , { status } "
@@ -193,33 +195,35 @@ def startCompetition(self) -> None:
193195 if status != 0 :
194196 raise RuntimeError (f"updateNotifierAlarm() returned { status } " )
195197
196- currentTimeUs , status = waitForNotifierAlarm (self ._notifier )
198+ self . _loopStartTimeUs , status = waitForNotifierAlarm (self ._notifier )
197199 if status != 0 :
198200 raise RuntimeError (
199- f"waitForNotifierAlarm() returned currentTimeUs= { currentTimeUs } status={ status } "
201+ f"waitForNotifierAlarm() returned _loopStartTimeUs= { self . _loopStartTimeUs } status={ status } "
200202 )
201203
202- if currentTimeUs == 0 :
204+ if self . _loopStartTimeUs == 0 :
203205 # when HAL_StopNotifier(self.notifier) is called the above waitForNotifierAlarm
204- # will return a currentTimeUs ==0 and the API requires robots to stop any loops.
206+ # will return a _loopStartTimeUs ==0 and the API requires robots to stop any loops.
205207 # See the API for waitForNotifierAlarm
206208 break
207209
208- self ._loopStartTimeUs = _getFPGATime ()
209- self ._runCallbackAndReschedule (callback , currentTimeUs )
210+ self ._runCallbackAndReschedule (callback )
210211
211212 # Process all other callbacks that are ready to run
212- while self ._callbacks .peek ().expirationUs <= currentTimeUs :
213+ while self ._callbacks .peek ().expirationUs <= self . _loopStartTimeUs :
213214 callback = self ._callbacks .pop ()
214- self ._runCallbackAndReschedule (callback , currentTimeUs )
215+ self ._runCallbackAndReschedule (callback )
215216 finally :
217+ # pytests hang on PC when we don't force a call to self._stopNotifier()
216218 self ._stopNotifier ()
217219
218- def _runCallbackAndReschedule (
219- self , callback : _Callback , currentTimeUs : microsecondsAsInt
220- ) -> None :
220+ def _runCallbackAndReschedule (self , callback : _Callback ) -> None :
221221 callback .func ()
222- callback .setNextStartTimeUs (currentTimeUs )
222+ # The c++ implementation used the current time before the callback ran,
223+ # to reschedule. By using _getFPGATime(), on a callback.func()
224+ # that ran long we immediately push the next invocation to the
225+ # following period.
226+ callback .setNextStartTimeUs (_getFPGATime ())
223227 self ._callbacks .add (callback )
224228
225229 def _stopNotifier (self ):
0 commit comments