@@ -155,6 +155,7 @@ def __init__(self, period: wpimath.units.seconds = kDefaultPeriod) -> None:
155155        self .addPeriodic (self ._loopFunc , period = self ._periodS )
156156
157157        self ._notifier , status  =  initializeNotifier ()
158+         print (f"{ self ._notifier } { status }  )
158159        if  status  !=  0 :
159160            raise  RuntimeError (
160161                f"initializeNotifier() returned { self ._notifier } { status }  
@@ -170,59 +171,65 @@ def startCompetition(self) -> None:
170171        """ 
171172        Provide an alternate "main loop" via startCompetition(). 
172173        """ 
173-         self .robotInit ()
174- 
175-         if  self .isSimulation ():
176-             self ._simulationInit ()
177- 
178-         # Tell the DS that the robot is ready to be enabled 
179-         print ("********** Robot program startup complete **********" )
180-         observeUserProgramStarting ()
181- 
182-         # Loop forever, calling the appropriate mode-dependent function 
183-         # (really not forever, there is a check for a break) 
184-         while  True :
185-             #  We don't have to check there's an element in the queue first because 
186-             #  there's always at least one (the constructor adds one). It's re-enqueued 
187-             #  at the end of the loop. 
188-             callback  =  self ._callbacks .pop ()
189- 
190-             status  =  updateNotifierAlarm (self ._notifier , callback .expirationUs )
191-             if  status  !=  0 :
192-                 raise  RuntimeError (f"updateNotifierAlarm() returned { status }  )
193- 
194-             currentTimeUs , status  =  waitForNotifierAlarm (self ._notifier )
195-             if  status  !=  0 :
196-                 raise  RuntimeError (
197-                     f"waitForNotifierAlarm() returned currentTimeUs={ currentTimeUs } { status }  
198-                 )
199- 
200-             if  currentTimeUs  ==  0 :
201-                 # when HAL_StopNotifier(self.notifier) is called the above waitForNotifierAlarm 
202-                 # will return a currentTimeUs==0 and the API requires robots to stop any loops. 
203-                 # See the API for waitForNotifierAlarm 
204-                 break 
205- 
206-             self ._loopStartTimeUs  =  _getFPGATime ()
207-             self ._runCallbackAndReschedule (callback , currentTimeUs )
208- 
209-             #  Process all other callbacks that are ready to run 
210-             while  self ._callbacks .peek ().expirationUs  <=  currentTimeUs :
174+         try :
175+             self .robotInit ()
176+ 
177+             if  self .isSimulation ():
178+                 self ._simulationInit ()
179+ 
180+             # Tell the DS that the robot is ready to be enabled 
181+             print ("********** Robot program startup complete **********" , flush = True )
182+             observeUserProgramStarting ()
183+ 
184+             # Loop forever, calling the appropriate mode-dependent function 
185+             # (really not forever, there is a check for a break) 
186+             while  True :
187+                 #  We don't have to check there's an element in the queue first because 
188+                 #  there's always at least one (the constructor adds one). It's re-enqueued 
189+                 #  at the end of the loop. 
211190                callback  =  self ._callbacks .pop ()
191+ 
192+                 status  =  updateNotifierAlarm (self ._notifier , callback .expirationUs )
193+                 if  status  !=  0 :
194+                     raise  RuntimeError (f"updateNotifierAlarm() returned { status }  )
195+ 
196+                 currentTimeUs , status  =  waitForNotifierAlarm (self ._notifier )
197+                 if  status  !=  0 :
198+                     raise  RuntimeError (
199+                         f"waitForNotifierAlarm() returned currentTimeUs={ currentTimeUs } { status }  
200+                     )
201+ 
202+                 if  currentTimeUs  ==  0 :
203+                     # 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. 
205+                     # See the API for waitForNotifierAlarm 
206+                     break 
207+ 
208+                 self ._loopStartTimeUs  =  _getFPGATime ()
212209                self ._runCallbackAndReschedule (callback , currentTimeUs )
213210
211+                 #  Process all other callbacks that are ready to run 
212+                 while  self ._callbacks .peek ().expirationUs  <=  currentTimeUs :
213+                     callback  =  self ._callbacks .pop ()
214+                     self ._runCallbackAndReschedule (callback , currentTimeUs )
215+         finally :
216+             self ._stopNotifier ()
217+ 
214218    def  _runCallbackAndReschedule (
215219        self , callback : _Callback , currentTimeUs : microsecondsAsInt 
216220    ) ->  None :
217221        callback .func ()
218222        callback .setNextStartTimeUs (currentTimeUs )
219223        self ._callbacks .add (callback )
220224
225+     def  _stopNotifier (self ):
226+         stopNotifier (self ._notifier )
227+ 
221228    def  endCompetition (self ) ->  None :
222229        """ 
223230        Ends the main loop in startCompetition(). 
224231        """ 
225-         stopNotifier ( self ._notifier )
232+         self ._stopNotifier ( )
226233
227234    def  getLoopStartTime (self ) ->  microsecondsAsInt :
228235        """ 
0 commit comments