@@ -34,8 +34,8 @@ class MagicRobot(wpilib.SampleRobot, metaclass=OrderedClass):
34
34
35
35
MagicRobot uses the :class:`.AutonomousModeSelector` to allow you
36
36
to define multiple autonomous modes and to select one of them via
37
- the SmartDashboard/SFX .
38
-
37
+ the SmartDashboard/Shuffleboard .
38
+
39
39
MagicRobot will set the following NetworkTables variables
40
40
automatically:
41
41
@@ -78,6 +78,8 @@ def robotInit(self):
78
78
self .__nt .putBoolean ("is_simulation" , self .isSimulation ())
79
79
self .__nt .putBoolean ("is_ds_attached" , self .ds .isDSAttached ())
80
80
81
+ self .watchdog = wpilib .Watchdog (self .control_loop_wait_time , self ._loop_overrun )
82
+
81
83
def createObjects (self ):
82
84
"""
83
85
You should override this and initialize all of your wpilib
@@ -183,9 +185,13 @@ def robotPeriodic(self):
183
185
The default implementation will update
184
186
SmartDashboard, LiveWindow and Shuffleboard.
185
187
"""
188
+ watchdog = self .watchdog
186
189
wpilib .SmartDashboard .updateValues ()
190
+ watchdog .addEpoch ("SmartDashboard" )
187
191
wpilib .LiveWindow .updateValues ()
192
+ watchdog .addEpoch ("LiveWindow" )
188
193
Shuffleboard .update ()
194
+ watchdog .addEpoch ("Shuffleboard" )
189
195
190
196
def onException (self , forceReport = False ):
191
197
"""
@@ -289,6 +295,7 @@ def autonomous(self):
289
295
self .control_loop_wait_time ,
290
296
(self ._execute_components , self ._update_feedback , self .robotPeriodic ),
291
297
self .onException ,
298
+ watchdog = self .watchdog ,
292
299
)
293
300
294
301
self ._on_mode_disable_components ()
@@ -301,6 +308,8 @@ def disabled(self):
301
308
302
309
.. warning:: Internal API, don't override
303
310
"""
311
+ watchdog = self .watchdog
312
+ watchdog .reset ()
304
313
305
314
self .__nt .putString ("mode" , "disabled" )
306
315
ds_attached = None
@@ -311,6 +320,7 @@ def disabled(self):
311
320
self .disabledInit ()
312
321
except :
313
322
self .onException (forceReport = True )
323
+ watchdog .addEpoch ("disabledInit()" )
314
324
315
325
with NotifierDelay (self .control_loop_wait_time ) as delay :
316
326
while self .isDisabled ():
@@ -323,10 +333,18 @@ def disabled(self):
323
333
self .disabledPeriodic ()
324
334
except :
325
335
self .onException ()
336
+ watchdog .addEpoch ("disabledPeriodic()" )
326
337
327
338
self ._update_feedback ()
328
339
self .robotPeriodic ()
340
+ watchdog .addEpoch ("robotPeriodic()" )
341
+ watchdog .disable ()
342
+
343
+ if watchdog .isExpired ():
344
+ watchdog .printEpochs ()
345
+
329
346
delay .wait ()
347
+ watchdog .reset ()
330
348
331
349
def operatorControl (self ):
332
350
"""
@@ -336,6 +354,8 @@ def operatorControl(self):
336
354
337
355
.. warning:: Internal API, don't override
338
356
"""
357
+ watchdog = self .watchdog
358
+ watchdog .reset ()
339
359
340
360
self .__nt .putString ("mode" , "teleop" )
341
361
# don't need to update this during teleop -- presumably will switch
@@ -350,6 +370,7 @@ def operatorControl(self):
350
370
self .teleopInit ()
351
371
except :
352
372
self .onException (forceReport = True )
373
+ watchdog .addEpoch ("teleopInit()" )
353
374
354
375
with NotifierDelay (self .control_loop_wait_time ) as delay :
355
376
while self .isOperatorControl () and self .isEnabled ():
@@ -358,17 +379,27 @@ def operatorControl(self):
358
379
self .teleopPeriodic ()
359
380
except :
360
381
self .onException ()
382
+ watchdog .addEpoch ("teleopPeriodic()" )
361
383
362
384
self ._execute_components ()
385
+
363
386
self ._update_feedback ()
364
387
self .robotPeriodic ()
388
+ watchdog .addEpoch ("robotPeriodic()" )
389
+ watchdog .disable ()
390
+
391
+ if watchdog .isExpired ():
392
+ watchdog .printEpochs ()
365
393
366
394
delay .wait ()
395
+ watchdog .reset ()
367
396
368
397
self ._on_mode_disable_components ()
369
398
370
399
def test (self ):
371
400
"""Called when the robot is in test mode"""
401
+ watchdog = self .watchdog
402
+ watchdog .reset ()
372
403
373
404
self .__nt .putString ("mode" , "test" )
374
405
self .__nt .putBoolean ("is_ds_attached" , self .ds .isDSAttached ())
@@ -378,6 +409,7 @@ def test(self):
378
409
self .testInit ()
379
410
except :
380
411
self .onException (forceReport = True )
412
+ watchdog .addEpoch ("testInit()" )
381
413
382
414
with NotifierDelay (self .control_loop_wait_time ) as delay :
383
415
while self .isTest () and self .isEnabled ():
@@ -386,26 +418,36 @@ def test(self):
386
418
self .testPeriodic ()
387
419
except :
388
420
self .onException ()
421
+ watchdog .addEpoch ("testPeriodic()" )
389
422
390
423
self ._update_feedback ()
391
424
self .robotPeriodic ()
425
+ watchdog .addEpoch ("robotPeriodic()" )
426
+ watchdog .disable ()
427
+
428
+ if watchdog .isExpired ():
429
+ watchdog .printEpochs ()
430
+
392
431
delay .wait ()
432
+ watchdog .reset ()
393
433
394
434
def _on_mode_enable_components (self ):
395
435
# initialize things
396
- for component in self ._components :
397
- if hasattr (component , "on_enable" ):
436
+ for _ , component in self ._components :
437
+ on_enable = getattr (component , "on_enable" , None )
438
+ if on_enable is not None :
398
439
try :
399
- component . on_enable ()
440
+ on_enable ()
400
441
except :
401
442
self .onException (forceReport = True )
402
443
403
444
def _on_mode_disable_components (self ):
404
445
# deinitialize things
405
- for component in self ._components :
406
- if hasattr (component , "on_disable" ):
446
+ for _ , component in self ._components :
447
+ on_disable = getattr (component , "on_disable" , None )
448
+ if on_disable is not None :
407
449
try :
408
- component . on_disable ()
450
+ on_disable ()
409
451
except :
410
452
self .onException (forceReport = True )
411
453
@@ -495,7 +537,6 @@ def _create_components(self):
495
537
496
538
# For each new component, perform magic injection
497
539
for cname , component in components :
498
- self ._components .append (component )
499
540
setup_tunables (component , cname , "components" )
500
541
self ._feedbacks += collect_feedbacks (component , cname , "components" )
501
542
self ._setup_vars (cname , component )
@@ -521,6 +562,8 @@ def _create_components(self):
521
562
if hasattr (mode , "setup" ):
522
563
mode .setup ()
523
564
565
+ self ._components = components
566
+
524
567
def _create_component (self , name , ctyp ):
525
568
# Create instance, set it on self
526
569
component = ctyp ()
@@ -641,13 +684,19 @@ def _update_feedback(self):
641
684
self .onException ()
642
685
continue
643
686
entry .setValue (value )
687
+ self .watchdog .addEpoch ("@magicbot.feedback" )
644
688
645
689
def _execute_components (self ):
646
- for component in self ._components :
690
+ for name , component in self ._components :
647
691
try :
648
692
component .execute ()
649
693
except :
650
694
self .onException ()
695
+ self .watchdog .addEpoch (name )
651
696
652
697
for reset_dict , component in self ._reset_components :
653
698
component .__dict__ .update (reset_dict )
699
+
700
+ def _loop_overrun (self ):
701
+ # TODO: print something here without making it extremely annoying
702
+ pass
0 commit comments