Skip to content

Commit a3cdbb5

Browse files
committed
magicbot: Adds addPeriodic
1 parent 2c535d4 commit a3cdbb5

File tree

1 file changed

+39
-1
lines changed

1 file changed

+39
-1
lines changed

magicbot/magicrobot.py

Lines changed: 39 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,10 +5,11 @@
55
import types
66
import typing
77

8-
from typing import Any, Callable
8+
from typing import Any, Callable, List, Tuple
99

1010
import hal
1111
import wpilib
12+
from wpilib import Notifier
1213

1314
from ntcore import NetworkTableInstance
1415

@@ -88,6 +89,11 @@ def __init__(self) -> None:
8889
self.__lv_update = wpilib.LiveWindow.updateValues
8990
# self.__sf_update = Shuffleboard.update
9091

92+
self._periodic_callbacks: typing.List[Tuple[Callable[[], None], float]] = []
93+
self._notifiers: List[Notifier] = []
94+
95+
self.loop_time = self.control_loop_wait_time
96+
9197
def _simulationInit(self) -> None:
9298
pass
9399

@@ -99,6 +105,16 @@ def __simulationPeriodic(self) -> None:
99105
self._simulationPeriodic()
100106
hal.simPeriodicAfter()
101107

108+
def addPeriodic(self, callback: Callable[[], None], period: float):
109+
"""
110+
Add a callback to run at a specific period with a starting time offset.
111+
112+
This is scheduled with MagicRobot's loop, so MagicRobot and the callback run synchronously.
113+
"""
114+
115+
print(f"Registering periodic: {callback.__name__}, every {period}s")
116+
self._periodic_callbacks.append((callback, period))
117+
102118
def robotInit(self) -> None:
103119
"""
104120
.. warning:: Internal API, don't override; use :meth:`createObjects` instead
@@ -558,6 +574,20 @@ def _test(self) -> None:
558574
wpilib.LiveWindow.setEnabled(False)
559575
# Shuffleboard.disableActuatorWidgets()
560576

577+
578+
def _stop_notifiers(self):
579+
for notifier in self._notifiers:
580+
notifier.stop()
581+
self._notifiers.clear()
582+
583+
def _restart_periodics(self):
584+
self._stop_notifiers()
585+
for callback, period in self._periodic_callbacks:
586+
notifier = Notifier(callback)
587+
notifier.setName(f"Periodic-{callback.__name__}")
588+
notifier.startPeriodic(period)
589+
self._notifiers.append(notifier)
590+
561591
def _on_mode_enable_components(self) -> None:
562592
# initialize things
563593
for _, component in self._components:
@@ -567,6 +597,7 @@ def _on_mode_enable_components(self) -> None:
567597
on_enable()
568598
except:
569599
self.onException(forceReport=True)
600+
self._restart_periodics()
570601

571602
def _on_mode_disable_components(self) -> None:
572603
# deinitialize things
@@ -577,6 +608,7 @@ def _on_mode_disable_components(self) -> None:
577608
on_disable()
578609
except:
579610
self.onException(forceReport=True)
611+
self._stop_notifiers()
580612

581613
def _create_components(self) -> None:
582614
#
@@ -737,6 +769,12 @@ def _do_periodics(self) -> None:
737769

738770
for reset_dict, component in self._reset_components:
739771
component.__dict__.update(reset_dict)
772+
773+
self.loop_time = max(self.control_loop_wait_time, self.watchdog.getTime())
774+
775+
def get_period(self) -> float:
776+
"""Get the period of the robot loop in seconds."""
777+
return self.loop_time
740778

741779
def _enabled_periodic(self) -> None:
742780
"""Run components and all periodic methods."""

0 commit comments

Comments
 (0)