Skip to content

Commit 965564f

Browse files
committed
Ported the ProfiledPIDSubsystem from the wpilib java source to Python
1 parent 27a3071 commit 965564f

File tree

2 files changed

+63
-0
lines changed

2 files changed

+63
-0
lines changed

commands2/__init__.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@
3333
from .pidcommand import PIDCommand
3434
from .pidsubsystem import PIDSubsystem
3535
from .printcommand import PrintCommand
36+
from .profiledpidsubsystem import ProfiledPIDSubsystem
3637
from .proxycommand import ProxyCommand
3738
from .proxyschedulecommand import ProxyScheduleCommand
3839
from .repeatcommand import RepeatCommand

commands2/profiledpidsubsystem.py

Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
# Copyright (c) FIRST and other WPILib contributors.
2+
# Open Source Software; you can modify and/or share it under the terms of
3+
# the WPILib BSD license file in the root directory of this project.
4+
5+
from wpimath.controller import ProfiledPIDController
6+
from .subsystem import Subsystem
7+
from wpimath.trajectory import TrapezoidProfile
8+
9+
10+
class ProfiledPIDSubsystem(Subsystem):
11+
def __init__(self, controller: ProfiledPIDController, initial_position: float = 0):
12+
super().__init__()
13+
self._m_controller = controller
14+
self._m_enabled = False
15+
self.setGoal(initial_position)
16+
17+
def periodic(self):
18+
"""Updates the output of the controller."""
19+
if self._m_enabled:
20+
self._useOutput(self._m_controller.calculate(self._getMeasurement()),
21+
self._m_controller.getSetpoint())
22+
23+
def get_controller(self) -> ProfiledPIDController:
24+
"""Returns the ProfiledPIDController."""
25+
return self._m_controller
26+
27+
def setGoal(self, goal: TrapezoidProfile.State | float):
28+
"""
29+
Sets the goal state for the subsystem.
30+
"""
31+
if isinstance(goal, TrapezoidProfile):
32+
self._m_controller.setGoal(goal)
33+
else:
34+
self._m_controller.setGoal(TrapezoidProfile.State(goal, 0))
35+
36+
def _useOutput(self, output: float, setpoint: TrapezoidProfile.State):
37+
"""
38+
Uses the output from the ProfiledPIDController.
39+
"""
40+
raise NotImplementedError("Subclasses must implement this method")
41+
42+
def _getMeasurement(self) -> float:
43+
"""
44+
Returns the measurement of the process variable used by the ProfiledPIDController.
45+
"""
46+
raise NotImplementedError("Subclasses must implement this method")
47+
48+
def enable(self):
49+
"""Enables the PID control. Resets the controller."""
50+
self._m_enabled = True
51+
self._m_controller.reset(self._getMeasurement())
52+
53+
def disable(self):
54+
"""Disables the PID control. Sets output to zero."""
55+
self._m_enabled = False
56+
self._useOutput(0, TrapezoidProfile.State())
57+
58+
def isEnabled(self) -> bool:
59+
"""
60+
Returns whether the controller is enabled.
61+
"""
62+
return self._m_enabled

0 commit comments

Comments
 (0)