@@ -55,16 +55,29 @@ def calcFutureExpirationUs(
5555        self , currentTimeUs : microsecondsAsInt 
5656    ) ->  microsecondsAsInt :
5757        # increment the expiration time by the number of full periods it's behind 
58-         # plus one to avoid rapid repeat fires from a large loop overrun. We assume 
59-         # currentTime ≥ startTimeUs rather than checking for it since the 
58+         # plus one to avoid rapid repeat fires from a large loop overrun. 
59+         # 
60+         # This routine is called when either: 
61+         #   this callback has never ran and self.expirationUs is 
62+         #   TimedRobot._starttimeUs and we are calculating where the first 
63+         #   expiration should be relative to TimedRobot._starttimeUs 
64+         # or: 
65+         #   this call back has ran and self.expirationUs is when it was scheduled to 
66+         #   expire and we are calculating when the next expirations should be relative 
67+         #   to the last scheduled expiration 
68+         # 
69+         # We assume currentTime ≥ self.expirationUs rather than checking for it since the 
6070        # callback wouldn't be running otherwise. 
61-         # todo does this math work? 
62-         # todo does the "// periodUs * periodUs" do the correct integer math? 
63-         return  (
64-             self .expirationUs 
65-             +  self ._periodUs 
71+         # 
72+         # We take when we previously expired or when we started: self.expirationUs 
73+         # add + self._periodUs to get at least one period in the future 
74+         # then calculate how many whole periods we are behind: 
75+         #   ((currentTimeUs - self.expirationUs) // self._periodUs) 
76+         # and multiply that by self._periodUs to calculate how much time in full 
77+         # periods we need to skip to catch up, and add that to the sum to calculate 
78+         # when we should run again. 
79+         return  self .expirationUs  +  self ._periodUs  \
6680            +  ((currentTimeUs  -  self .expirationUs ) //  self ._periodUs ) *  self ._periodUs 
67-         )
6881
6982    def  setNextStartTimeUs (self , currentTimeUs : microsecondsAsInt ) ->  None :
7083        self .expirationUs  =  self .calcFutureExpirationUs (currentTimeUs )
@@ -129,6 +142,8 @@ def __init__(self, period: wpimath.units.seconds = kDefaultPeriod) -> None:
129142        """ 
130143        super ().__init__ (period )
131144
145+         # All periodic functions created by addPeriodic are relative 
146+         # to this self._startTimeUs 
132147        self ._startTimeUs  =  _getFPGATime ()
133148        self ._callbacks  =  _OrderedList ()
134149        self ._loopStartTimeUs  =  0 
0 commit comments